1799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe/*
2799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * Copyright (C) 2015 The Android Open Source Project
3799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe *
4799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License");
5799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * you may not use this file except in compliance with the License.
6799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * You may obtain a copy of the License at
7799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe *
8799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe *      http://www.apache.org/licenses/LICENSE-2.0
9799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe *
10799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * Unless required by applicable law or agreed to in writing, software
11799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS,
12799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * See the License for the specific language governing permissions and
14799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe * limitations under the License.
15799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe */
16799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
17799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime.h"
18799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
1989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe#include <limits>
200bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe#include <locale>
2189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
2289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe#include "base/casts.h"
23656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe#include "base/memory_tool.h"
24799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "class_linker.h"
25799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "common_runtime_test.h"
26400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "dex_instruction.h"
27799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle.h"
28799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle_scope-inl.h"
29400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "interpreter/interpreter_common.h"
30799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/class_loader.h"
31799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/string-inl.h"
32799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "runtime.h"
33799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "scoped_thread_state_change.h"
34799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "thread.h"
350bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe#include "transaction.h"
36799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
37799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace art {
38799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace interpreter {
39799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
40799681b176ad25437ce2849639f54f610dcbf684Andreas Gampeclass UnstartedRuntimeTest : public CommonRuntimeTest {
41799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe protected:
42799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
43799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // test friends.
44799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
45799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Methods that intercept available libcore implementations.
46799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#define UNSTARTED_DIRECT(Name, SigIgnored)                 \
47799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  static void Unstarted ## Name(Thread* self,              \
48799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                ShadowFrame* shadow_frame, \
49799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                JValue* result,            \
50799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                size_t arg_offset)         \
5190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {        \
52799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
53799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
54799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h"
55799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
56799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST
57799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST
58799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_DIRECT
59799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
60799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Methods that are native.
61e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define UNSTARTED_JNI(Name, SigIgnored)                       \
62799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  static void UnstartedJNI ## Name(Thread* self,              \
63e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                   ArtMethod* method,         \
64799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   mirror::Object* receiver,  \
65799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   uint32_t* args,            \
66799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   JValue* result)            \
6790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {           \
68799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
69799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
70799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h"
71799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
72799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST
73799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST
74799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_JNI
7585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
7685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Helpers for ArrayCopy.
7785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //
7885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
7985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //       of three everywhere. That is enough to test all cases.
8085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
8185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  static mirror::ObjectArray<mirror::Object>* CreateObjectArray(
8285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      Thread* self,
8385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      mirror::Class* component_type,
8485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      const StackHandleScope<3>& data)
8585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
8685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Runtime* runtime = Runtime::Current();
8785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    mirror::Class* array_type = runtime->GetClassLinker()->FindArrayClass(self, &component_type);
8885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK(array_type != nullptr);
8985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    mirror::ObjectArray<mirror::Object>* result =
9085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
9185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK(result != nullptr);
9285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    for (size_t i = 0; i < 3; ++i) {
9385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      result->Set(static_cast<int32_t>(i), data.GetReference(i));
9485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      CHECK(!self->IsExceptionPending());
9585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
9685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    return result;
9785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
9885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
9985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array,
10085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                               const StackHandleScope<3>& data)
10185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
10285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK_EQ(array->GetLength(), 3);
10385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK_EQ(data.NumberOfReferences(), 3U);
10485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    for (size_t i = 0; i < 3; ++i) {
10585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
10685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
10785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
10885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
10985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  void RunArrayCopy(Thread* self,
11085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    ShadowFrame* tmp,
11185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    bool expect_exception,
11285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::ObjectArray<mirror::Object>* src,
11385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t src_pos,
11485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::ObjectArray<mirror::Object>* dst,
11585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t dst_pos,
11685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t length)
11785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
11885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    JValue result;
11985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVRegReference(0, src);
12085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(1, src_pos);
12185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVRegReference(2, dst);
12285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(3, dst_pos);
12385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(4, length);
12485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    UnstartedSystemArraycopy(self, tmp, &result, 0);
12585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    bool exception_pending = self->IsExceptionPending();
12685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    EXPECT_EQ(exception_pending, expect_exception);
12785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    if (exception_pending) {
12885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      self->ClearException();
12985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
13085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
13185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
13285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  void RunArrayCopy(Thread* self,
13385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    ShadowFrame* tmp,
13485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    bool expect_exception,
13585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::Class* src_component_class,
13685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::Class* dst_component_class,
13785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& src_data,
13885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t src_pos,
13985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& dst_data,
14085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t dst_pos,
14185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t length,
14285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& expected_result)
14385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
14485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_misc(self);
14585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
14685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
14785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::ObjectArray<mirror::Object>> src_handle(
14885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
14985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
15085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
15185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
15285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
15385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
15485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
15585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 expect_exception,
15685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 src_handle.Get(),
15785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 src_pos,
15885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 dst_handle.Get(),
15985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 dst_pos,
16085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 length);
16185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CheckObjectArray(dst_handle.Get(), expected_result);
16285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
16389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
16489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  void TestCeilFloor(bool ceil,
16589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     Thread* self,
16689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     ShadowFrame* tmp,
16789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     double const test_pairs[][2],
16889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     size_t num_pairs)
16989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
17089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe    for (size_t i = 0; i < num_pairs; ++i) {
17189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      tmp->SetVRegDouble(0, test_pairs[i][0]);
17289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
17389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      JValue result;
17489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      if (ceil) {
17589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe        UnstartedMathCeil(self, tmp, &result, 0);
17689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      } else {
17789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe        UnstartedMathFloor(self, tmp, &result, 0);
17889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      }
17989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
18089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      ASSERT_FALSE(self->IsExceptionPending());
18189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
18289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      // We want precise results.
18389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
18489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
18589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
18689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe    }
18789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  }
1880bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
1890bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
1900bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  // loading code doesn't work under transactions.
1910bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  void PrepareForAborts() SHARED_REQUIRES(Locks::mutator_lock_) {
1920bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass(
1930bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        Thread::Current(),
1940bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        Transaction::kAbortExceptionSignature,
1950bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        ScopedNullHandle<mirror::ClassLoader>());
1960bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    CHECK(result != nullptr);
1970bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  }
198799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe};
199799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
200799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
201799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
202799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
203799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
204799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
205799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
206799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
207799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
208799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
209799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
210799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
211799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < kBaseLen; ++i) {
212799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
213799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
214799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekByte(self, tmp, &result, 0);
215799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
216799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
217799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
218799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
219799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
220799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
221799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
222799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
223799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
224799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
225799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
226799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
227799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
228799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
229799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
230799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
231799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
232799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
233799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int16_t);
234799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
235799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
236799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
237799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekShort(self, tmp, &result, 0);
238799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
239799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int16_t unaligned_short __attribute__ ((aligned (1)));
240799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
241799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetS(), *short_ptr);
242799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
243799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
244799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
245799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
246799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
247799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
248799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
249799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
250799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
251799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
252799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
253799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
254799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
255799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
256799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
257799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
258799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int32_t);
259799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
260799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
261799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
262799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekInt(self, tmp, &result, 0);
263799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
264799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int32_t unaligned_int __attribute__ ((aligned (1)));
265799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
266799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetI(), *int_ptr);
267799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
268799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
269799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
270799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
271799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
272799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
273799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
274799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
275799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
276799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
277799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
278799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
279799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
280799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
281799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
282799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
283799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int64_t);
284799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
285799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
286799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
287799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekLong(self, tmp, &result, 0);
288799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
289799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int64_t unaligned_long __attribute__ ((aligned (1)));
290799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
291799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetJ(), *long_ptr);
292799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
293799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
294799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
295799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
296799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
297799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
298799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
299799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
300799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
301799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  StackHandleScope<2> hs(self);
302799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // TODO: Actual UTF.
303799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const char base_string[] = "abcdefghijklmnop";
304799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Handle<mirror::String> h_test_string(hs.NewHandle(
305799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      mirror::String::AllocFromModifiedUtf8(self, base_string)));
306799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
307799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Handle<mirror::CharArray> h_char_array(hs.NewHandle(
308799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      mirror::CharArray::Alloc(self, kBaseLen)));
309799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // A buffer so we can make sure we only modify the elements targetted.
310799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  uint16_t buf[kBaseLen];
311799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
312799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
313799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
314799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
315799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
316799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    for (int32_t count = 0; count <= kBaseLen; ++count) {
317799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
318799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        // Only do it when in bounds.
319799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
320799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVRegReference(0, h_test_string.Get());
321799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(1, start_index);
322799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(2, count);
323799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVRegReference(3, h_char_array.Get());
324799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(3, trg_offset);
325799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
326799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Copy the char_array into buf.
327799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
328799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
329799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          UnstartedStringCharAt(self, tmp, &result, 0);
330799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
331799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          uint16_t* data = h_char_array->GetData();
332799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
333799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          bool success = true;
334799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
335799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // First segment should be unchanged.
336799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = 0; i < trg_offset; ++i) {
337799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i]);
338799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
339799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Second segment should be a copy.
340799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
341799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i - trg_offset + start_index]);
342799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
343799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Third segment should be unchanged.
344799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
345799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i]);
346799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
347799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
348799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          EXPECT_TRUE(success);
349799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        }
350799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      }
351799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    }
352799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
353799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
354799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
355799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
356799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
357799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringCharAt) {
358799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
359799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
360799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
361799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // TODO: Actual UTF.
362799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const char* base_string = "abcdefghijklmnop";
363799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t base_len = static_cast<int32_t>(strlen(base_string));
364799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
365799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
366799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
367799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
368799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
369799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < base_len; ++i) {
370799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegReference(0, test_string);
371799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVReg(1, i);
372799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
373799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedStringCharAt(self, tmp, &result, 0);
374799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
375799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetI(), base_string[i]);
376799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
377799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
378799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
379799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
380799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
381400ce0087ed0a41f385b55d555afc4616166965aJeff HaoTEST_F(UnstartedRuntimeTest, StringInit) {
382400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  Thread* self = Thread::Current();
383400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ScopedObjectAccess soa(self);
384400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::Class* klass = mirror::String::GetJavaLangString();
385e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V",
386e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                                      sizeof(void*));
387400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
388400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  // create instruction data for invoke-direct {v0, v1} of method with fake index
389400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
390400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  const Instruction* inst = Instruction::At(inst_data);
391400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
392400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  JValue result;
393400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
394400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  const char* base_string = "hello_world";
395400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string);
396400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, "");
397400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  shadow_frame->SetVRegReference(0, reference_empty_string);
398400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  shadow_frame->SetVRegReference(1, string_arg);
399400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
400400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
401400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL());
402400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
403400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
404400ce0087ed0a41f385b55d555afc4616166965aJeff Hao                   string_arg->GetLength() * sizeof(uint16_t)), 0);
405400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
406400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
407400ce0087ed0a41f385b55d555afc4616166965aJeff Hao}
408400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
40985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// Tests the exceptions that should be checked before modifying the destination.
41085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// (Doesn't check the object vs primitive case ATM.)
41185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
41285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Thread* self = Thread::Current();
41385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ScopedObjectAccess soa(self);
41485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  JValue result;
41585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
41685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
41785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
41885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //       allocate.
41985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<2> hs_misc(self);
42085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::Class> object_class(
42185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
42285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
42385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<3> hs_data(self);
42485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
42585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
42685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
42785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
42885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::ObjectArray<mirror::Object>> array(
42985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
43085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
43185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
43285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
43385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
43485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
43585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
43685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
43785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
43885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  mirror::ObjectArray<mirror::Object>* class_as_array =
43985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get());
44085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0);
44185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0);
44285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
44385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
44485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe}
44585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
44685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
44785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Thread* self = Thread::Current();
44885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ScopedObjectAccess soa(self);
44985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  JValue result;
45085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
45185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
45285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<1> hs_object(self);
45385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::Class> object_class(
45485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
45585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
45685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
45785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
45885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
45985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
46085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
46185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
46285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
46385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
46485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
46585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
46685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
46785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
46885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
46985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
47085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(0));
47185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(1));
47285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(1));
47385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
47485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
47585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
47685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 false,
47785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
47885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
47985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
48085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
48185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
48285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 2,
48385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
48485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
48585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
48685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
48785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
48885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
48985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
49085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
49185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
49285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
49385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
49485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
49585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
49685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
49785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
49885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
49985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
50085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
50185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(0));
50285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(1));
50385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(2));
50485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
50585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
50685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
50785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 false,
50885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
50985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 mirror::String::GetJavaLangString(),
51085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
51185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
51285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
51385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
51485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
51585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
51685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
51785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
51885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
51985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,*,3] into [4,5,6] = [1,5,6] + exc
52085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
52185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
52285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
52385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::GetJavaLangString());
52485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
52585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
52685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
52785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
52885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
52985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
53085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
53185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
53285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(0));
53385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(1));
53485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(2));
53585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
53685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
53785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
53885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 true,
53985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
54085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 mirror::String::GetJavaLangString(),
54185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
54285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 0,
54385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
54485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 0,
54585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 3,
54685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
54785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
54885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
54985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
55085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe}
55185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
55213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
55313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  Thread* self = Thread::Current();
55413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ScopedObjectAccess soa(self);
55513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
55613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
55713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
55813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
55913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // suffixes).
56013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr const char* test_string = "-2147483646";
56113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr int32_t test_values[] = {
56213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe                6,
56313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe               46,
56413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe              646,
56513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe             3646,
56613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe            83646,
56713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe           483646,
56813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe          7483646,
56913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe         47483646,
57013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        147483646,
57113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe       2147483646,
57213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe      -2147483646
57313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  };
57413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
57513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  static_assert(arraysize(test_values) == 11U, "test_values");
57613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  CHECK_EQ(strlen(test_string), 11U);
57713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
57813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  for (size_t i = 0; i <= 10; ++i) {
57913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    const char* test_value = &test_string[10 - i];
58013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
58113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    StackHandleScope<1> hs_str(self);
58213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    Handle<mirror::String> h_str(
58313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
58413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_NE(h_str.Get(), nullptr);
58513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
58613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
58713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    tmp->SetVRegReference(0, h_str.Get());
58813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
58913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    JValue result;
59013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    UnstartedIntegerParseInt(self, tmp, &result, 0);
59113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
59213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
59313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    EXPECT_EQ(result.GetI(), test_values[i]);
59413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  }
59513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
59613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
59713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe}
59813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
59913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe// Right now the same as Integer.Parse
60013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, LongParseLongTest) {
60113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  Thread* self = Thread::Current();
60213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ScopedObjectAccess soa(self);
60313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
60413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
60513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
60613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
60713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // suffixes).
60813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr const char* test_string = "-2147483646";
60913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr int64_t test_values[] = {
61013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe                6,
61113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe               46,
61213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe              646,
61313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe             3646,
61413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe            83646,
61513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe           483646,
61613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe          7483646,
61713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe         47483646,
61813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        147483646,
61913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe       2147483646,
62013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe      -2147483646
62113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  };
62213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
62313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  static_assert(arraysize(test_values) == 11U, "test_values");
62413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  CHECK_EQ(strlen(test_string), 11U);
62513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
62613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  for (size_t i = 0; i <= 10; ++i) {
62713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    const char* test_value = &test_string[10 - i];
62813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
62913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    StackHandleScope<1> hs_str(self);
63013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    Handle<mirror::String> h_str(
63113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
63213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_NE(h_str.Get(), nullptr);
63313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
63413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
63513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    tmp->SetVRegReference(0, h_str.Get());
63613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
63713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    JValue result;
63813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    UnstartedLongParseLong(self, tmp, &result, 0);
63913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
64013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
64113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    EXPECT_EQ(result.GetJ(), test_values[i]);
64213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  }
64313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
64413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
64513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe}
64613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
64789e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Ceil) {
64889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  Thread* self = Thread::Current();
64989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ScopedObjectAccess soa(self);
65089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
65189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
65289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
65389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double nan = std::numeric_limits<double>::quiet_NaN();
65489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double inf = std::numeric_limits<double>::infinity();
65589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
65689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
65789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double test_pairs[][2] = {
65889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.0, -0.0 },
65989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.0,  0.0 },
66089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.5, -0.0 },
66189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -1.0, -1.0 },
66289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.5,  1.0 },
66389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  1.0,  1.0 },
66489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  nan,  nan },
66589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  inf,  inf },
66689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -inf, -inf },
66789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld1,  ld1 },
66889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld2,  ld2 }
66989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  };
67089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
67189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));
67289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
67389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
67489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe}
67589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
67689e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Floor) {
67789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  Thread* self = Thread::Current();
67889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ScopedObjectAccess soa(self);
67989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
68089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
68189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
68289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double nan = std::numeric_limits<double>::quiet_NaN();
68389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double inf = std::numeric_limits<double>::infinity();
68489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
68589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
68689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double test_pairs[][2] = {
68789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.0, -0.0 },
68889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.0,  0.0 },
68989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.5, -1.0 },
69089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -1.0, -1.0 },
69189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.5,  0.0 },
69289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  1.0,  1.0 },
69389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  nan,  nan },
69489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  inf,  inf },
69589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -inf, -inf },
69689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld1,  ld1 },
69789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld2,  ld2 }
69889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  };
69989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
70089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));
70189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
70289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
70389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe}
70489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
7050bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas GampeTEST_F(UnstartedRuntimeTest, ToLowerUpper) {
7060bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  Thread* self = Thread::Current();
7070bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  ScopedObjectAccess soa(self);
7080bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7090bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
7100bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7110bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  std::locale c_locale("C");
7120bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7130bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  // Check ASCII.
7140bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  for (uint32_t i = 0; i < 128; ++i) {
7150bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    bool c_upper = std::isupper(static_cast<char>(i), c_locale);
7160bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    bool c_lower = std::islower(static_cast<char>(i), c_locale);
7170bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    EXPECT_FALSE(c_upper && c_lower) << i;
7180bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7190bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    // Check toLowerCase.
7200bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    {
7210bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      JValue result;
7220bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7230bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
7240bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_FALSE(self->IsExceptionPending());
7250bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      uint32_t lower_result = static_cast<uint32_t>(result.GetI());
7260bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      if (c_lower) {
7270bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        EXPECT_EQ(i, lower_result);
7280bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      } else if (c_upper) {
7290bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
7300bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe                  lower_result);
7310bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      } else {
7320bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        EXPECT_EQ(i, lower_result);
7330bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      }
7340bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    }
7350bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7360bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    // Check toUpperCase.
7370bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    {
7380bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      JValue result2;
7390bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7400bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
7410bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_FALSE(self->IsExceptionPending());
7420bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
7430bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      if (c_upper) {
7440bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        EXPECT_EQ(i, upper_result);
7450bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      } else if (c_lower) {
7460bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
7470bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe                  upper_result);
7480bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      } else {
7490bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe        EXPECT_EQ(i, upper_result);
7500bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      }
7510bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    }
7520bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  }
7530bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7540bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  // Check abort for other things. Can't test all.
7550bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7560bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  PrepareForAborts();
7570bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
7580bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  for (uint32_t i = 128; i < 256; ++i) {
7590bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    {
7600bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      JValue result;
7610bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7620bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Transaction transaction;
7630bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->EnterTransactionMode(&transaction);
7640bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
7650bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->ExitTransactionMode();
7660bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
7670bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(transaction.IsAborted());
7680bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    }
7690bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    {
7700bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      JValue result;
7710bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7720bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Transaction transaction;
7730bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->EnterTransactionMode(&transaction);
7740bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      UnstartedCharacterToUpperCase(self, tmp, &result, 0);
7750bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->ExitTransactionMode();
7760bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
7770bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(transaction.IsAborted());
7780bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    }
7790bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  }
7800bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
7810bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    {
7820bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      JValue result;
7830bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7840bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Transaction transaction;
7850bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->EnterTransactionMode(&transaction);
7860bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
7870bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->ExitTransactionMode();
7880bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
7890bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(transaction.IsAborted());
7900bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    }
7910bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    {
7920bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      JValue result;
7930bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7940bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Transaction transaction;
7950bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->EnterTransactionMode(&transaction);
7960bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      UnstartedCharacterToUpperCase(self, tmp, &result, 0);
7970bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      Runtime::Current()->ExitTransactionMode();
7980bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
7990bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe      ASSERT_TRUE(transaction.IsAborted());
8000bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe    }
8010bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  }
8020bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
8030bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
8040bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe}
8050bdce99fcecdadcbafc8e7a9bb92f491a4f37b2aAndreas Gampe
8068c5889a3bdefd7dc84494ec824d495913f2362a9Andreas GampeTEST_F(UnstartedRuntimeTest, Sin) {
8078c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  Thread* self = Thread::Current();
8088c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ScopedObjectAccess soa(self);
8098c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8108c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
8118c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8128c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  // Test an important value, PI/6. That's the one we see in practice.
8138c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
8148c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
8158c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8168c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  JValue result;
8178c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  UnstartedMathSin(self, tmp, &result, 0);
8188c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8198c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
8208c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
8218c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8228c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
8238c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe}
8248c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8258c5889a3bdefd7dc84494ec824d495913f2362a9Andreas GampeTEST_F(UnstartedRuntimeTest, Cos) {
8268c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  Thread* self = Thread::Current();
8278c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ScopedObjectAccess soa(self);
8288c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8298c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
8308c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8318c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  // Test an important value, PI/6. That's the one we see in practice.
8328c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
8338c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
8348c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8358c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  JValue result;
8368c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  UnstartedMathCos(self, tmp, &result, 0);
8378c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8388c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
8398c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
8408c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8418c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
8428c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe}
8438c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8448c5889a3bdefd7dc84494ec824d495913f2362a9Andreas GampeTEST_F(UnstartedRuntimeTest, Pow) {
845656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe  // Valgrind seems to get this wrong, actually. Disable for valgrind.
846656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe  if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
847656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe    return;
848656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe  }
849656fc8a586d56101e5d729bffc45e7303321c119Andreas Gampe
8508c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  Thread* self = Thread::Current();
8518c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ScopedObjectAccess soa(self);
8528c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8538c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
8548c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8558c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  // Test an important pair.
8568c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
8578c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
8588c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8598c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
8608c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
8618c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8628c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  JValue result;
8638c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  UnstartedMathPow(self, tmp, &result, 0);
8648c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8658c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
8668c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
8678c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
8688c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
8698c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe}
8708c5889a3bdefd7dc84494ec824d495913f2362a9Andreas Gampe
871799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}  // namespace interpreter
872799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}  // namespace art
873