unstarted_runtime_test.cc revision 16d1dd86dca33520b44d9802695e19d3b658af3e
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>
208ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe#include <locale>
2189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
2289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe#include "base/casts.h"
23542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe#include "base/enums.h"
24b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe#include "base/memory_tool.h"
25799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "class_linker.h"
26799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "common_runtime_test.h"
27400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "dex_instruction.h"
28799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle.h"
29799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle_scope-inl.h"
30400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "interpreter/interpreter_common.h"
31799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/class_loader.h"
329486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe#include "mirror/object_array-inl.h"
339486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe#include "mirror/object-inl.h"
34799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/string-inl.h"
35799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "runtime.h"
360795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h"
37799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "thread.h"
388ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe#include "transaction.h"
39799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
40799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace art {
41799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace interpreter {
42799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
43799681b176ad25437ce2849639f54f610dcbf684Andreas Gampeclass UnstartedRuntimeTest : public CommonRuntimeTest {
44799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe protected:
45799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
46799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // test friends.
47799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
48799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Methods that intercept available libcore implementations.
49799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#define UNSTARTED_DIRECT(Name, SigIgnored)                 \
50799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  static void Unstarted ## Name(Thread* self,              \
51799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                ShadowFrame* shadow_frame, \
52799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                JValue* result,            \
53799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                size_t arg_offset)         \
54bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {        \
55799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
56799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
57799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h"
58799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
59799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST
60799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST
61799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_DIRECT
62799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
63799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Methods that are native.
64e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define UNSTARTED_JNI(Name, SigIgnored)                       \
65799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  static void UnstartedJNI ## Name(Thread* self,              \
66e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                   ArtMethod* method,         \
67799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   mirror::Object* receiver,  \
68799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   uint32_t* args,            \
69799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   JValue* result)            \
70bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {           \
71799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
72799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
73799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h"
74799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
75799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST
76799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST
77799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_JNI
7885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
7985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Helpers for ArrayCopy.
8085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //
8185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
8285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //       of three everywhere. That is enough to test all cases.
8385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
8485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  static mirror::ObjectArray<mirror::Object>* CreateObjectArray(
8585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      Thread* self,
86bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier      ObjPtr<mirror::Class> component_type,
8785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      const StackHandleScope<3>& data)
88bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
8985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Runtime* runtime = Runtime::Current();
90bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier    ObjPtr<mirror::Class> array_type =
91bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier        runtime->GetClassLinker()->FindArrayClass(self, &component_type);
9285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK(array_type != nullptr);
93bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier    ObjPtr<mirror::ObjectArray<mirror::Object>> result =
9485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
9585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK(result != nullptr);
9685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    for (size_t i = 0; i < 3; ++i) {
9785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      result->Set(static_cast<int32_t>(i), data.GetReference(i));
9885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      CHECK(!self->IsExceptionPending());
9985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
100bc5a795c0d486c84913d987cad5846ded840cea6Mathieu Chartier    return result.Ptr();
10185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
10285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
10385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array,
10485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                               const StackHandleScope<3>& data)
105bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
10685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK_EQ(array->GetLength(), 3);
10785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK_EQ(data.NumberOfReferences(), 3U);
10885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    for (size_t i = 0; i < 3; ++i) {
10985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
11085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
11185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
11285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
11385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  void RunArrayCopy(Thread* self,
11485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    ShadowFrame* tmp,
11585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    bool expect_exception,
11685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::ObjectArray<mirror::Object>* src,
11785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t src_pos,
11885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::ObjectArray<mirror::Object>* dst,
11985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t dst_pos,
12085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t length)
121bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
12285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    JValue result;
12385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVRegReference(0, src);
12485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(1, src_pos);
12585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVRegReference(2, dst);
12685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(3, dst_pos);
12785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(4, length);
12885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    UnstartedSystemArraycopy(self, tmp, &result, 0);
12985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    bool exception_pending = self->IsExceptionPending();
13085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    EXPECT_EQ(exception_pending, expect_exception);
13185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    if (exception_pending) {
13285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      self->ClearException();
13385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
13485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
13585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
13685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  void RunArrayCopy(Thread* self,
13785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    ShadowFrame* tmp,
13885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    bool expect_exception,
13985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::Class* src_component_class,
14085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::Class* dst_component_class,
14185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& src_data,
14285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t src_pos,
14385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& dst_data,
14485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t dst_pos,
14585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t length,
14685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& expected_result)
147bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
14885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_misc(self);
14985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
15085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
15185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::ObjectArray<mirror::Object>> src_handle(
15285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
15385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
15485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
15585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
15685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
15785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
15885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
15985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 expect_exception,
16085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 src_handle.Get(),
16185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 src_pos,
16285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 dst_handle.Get(),
16385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 dst_pos,
16485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 length);
16585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CheckObjectArray(dst_handle.Get(), expected_result);
16685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
16789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
16889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  void TestCeilFloor(bool ceil,
16989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     Thread* self,
17089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     ShadowFrame* tmp,
17189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     double const test_pairs[][2],
17289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe                     size_t num_pairs)
173bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
17489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe    for (size_t i = 0; i < num_pairs; ++i) {
17589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      tmp->SetVRegDouble(0, test_pairs[i][0]);
17689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
17789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      JValue result;
17889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      if (ceil) {
17989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe        UnstartedMathCeil(self, tmp, &result, 0);
18089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      } else {
18189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe        UnstartedMathFloor(self, tmp, &result, 0);
18289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      }
18389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
18489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      ASSERT_FALSE(self->IsExceptionPending());
18589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
18689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      // We want precise results.
18789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
18889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
18989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
19089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe    }
19189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  }
1928ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
1938ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
1948ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  // loading code doesn't work under transactions.
195bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
1968ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass(
1978ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        Thread::Current(),
1988ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        Transaction::kAbortExceptionSignature,
1998ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        ScopedNullHandle<mirror::ClassLoader>());
2008ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    CHECK(result != nullptr);
2018ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  }
202799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe};
203799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
204799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
205799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
206799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
207799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
208799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
209799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
210799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
211799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
212799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
213799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
214799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
215799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < kBaseLen; ++i) {
216799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
217799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
218799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekByte(self, tmp, &result, 0);
219799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
220799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
221799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
222799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
223799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
224799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
225799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
226799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
227799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
228799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
229799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
230799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
231799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
232799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
233799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
234799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
235799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
236799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
237799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int16_t);
238799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
239799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
240799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
241799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekShort(self, tmp, &result, 0);
242799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
243799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int16_t unaligned_short __attribute__ ((aligned (1)));
244799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
245799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetS(), *short_ptr);
246799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
247799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
248799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
249799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
250799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
251799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
252799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
253799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
254799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
255799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
256799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
257799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
258799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
259799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
260799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
261799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
262799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int32_t);
263799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
264799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
265799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
266799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekInt(self, tmp, &result, 0);
267799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
268799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int32_t unaligned_int __attribute__ ((aligned (1)));
269799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
270799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetI(), *int_ptr);
271799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
272799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
273799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
274799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
275799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
276799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
277799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
278799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
279799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
280799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
281799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
282799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
283799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
284799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
285799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
286799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
287799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int64_t);
288799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
289799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
290799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
291799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekLong(self, tmp, &result, 0);
292799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
293799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int64_t unaligned_long __attribute__ ((aligned (1)));
294799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
295799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetJ(), *long_ptr);
296799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
297799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
298799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
299799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
300799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
301799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
302799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
303799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
304799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
305799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  StackHandleScope<2> hs(self);
306799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // TODO: Actual UTF.
307799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const char base_string[] = "abcdefghijklmnop";
308799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Handle<mirror::String> h_test_string(hs.NewHandle(
309799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      mirror::String::AllocFromModifiedUtf8(self, base_string)));
310799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
311799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Handle<mirror::CharArray> h_char_array(hs.NewHandle(
312799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      mirror::CharArray::Alloc(self, kBaseLen)));
313799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // A buffer so we can make sure we only modify the elements targetted.
314799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  uint16_t buf[kBaseLen];
315799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
316799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
317799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
318799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
319799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
320799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    for (int32_t count = 0; count <= kBaseLen; ++count) {
321799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
322799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        // Only do it when in bounds.
323799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
324799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVRegReference(0, h_test_string.Get());
325799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(1, start_index);
326799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(2, count);
327799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVRegReference(3, h_char_array.Get());
328799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(3, trg_offset);
329799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
330799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Copy the char_array into buf.
331799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
332799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
333799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          UnstartedStringCharAt(self, tmp, &result, 0);
334799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
335799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          uint16_t* data = h_char_array->GetData();
336799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
337799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          bool success = true;
338799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
339799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // First segment should be unchanged.
340799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = 0; i < trg_offset; ++i) {
341799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i]);
342799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
343799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Second segment should be a copy.
344799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
345799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i - trg_offset + start_index]);
346799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
347799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Third segment should be unchanged.
348799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
349799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i]);
350799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
351799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
352799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          EXPECT_TRUE(success);
353799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        }
354799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      }
355799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    }
356799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
357799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
358799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
359799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
360799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
361799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringCharAt) {
362799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
363799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
364799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
365799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // TODO: Actual UTF.
366799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const char* base_string = "abcdefghijklmnop";
367799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t base_len = static_cast<int32_t>(strlen(base_string));
368799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
369799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
370799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
371799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
372799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
373799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < base_len; ++i) {
374799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegReference(0, test_string);
375799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVReg(1, i);
376799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
377799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedStringCharAt(self, tmp, &result, 0);
378799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
379799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetI(), base_string[i]);
380799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
381799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
382799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
383799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
384799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
385400ce0087ed0a41f385b55d555afc4616166965aJeff HaoTEST_F(UnstartedRuntimeTest, StringInit) {
386400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  Thread* self = Thread::Current();
387400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ScopedObjectAccess soa(self);
388400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::Class* klass = mirror::String::GetJavaLangString();
389fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing  ArtMethod* method =
390ba118827465d12177f3996e50133960087b1c916Vladimir Marko      klass->FindConstructor("(Ljava/lang/String;)V",
391ba118827465d12177f3996e50133960087b1c916Vladimir Marko                             Runtime::Current()->GetClassLinker()->GetImagePointerSize());
392ba118827465d12177f3996e50133960087b1c916Vladimir Marko  ASSERT_TRUE(method != nullptr);
393400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
394400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  // create instruction data for invoke-direct {v0, v1} of method with fake index
395400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
396400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  const Instruction* inst = Instruction::At(inst_data);
397400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
398400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  JValue result;
399400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
400400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  const char* base_string = "hello_world";
401400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string);
402400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, "");
403400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  shadow_frame->SetVRegReference(0, reference_empty_string);
404400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  shadow_frame->SetVRegReference(1, string_arg);
405400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
406400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
407400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL());
408400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
4093aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo
4103aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo  if (string_arg->IsCompressed() && string_result->IsCompressed()) {
4113aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo    EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
4123aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo                     string_arg->GetLength() * sizeof(uint8_t)), 0);
4133aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo  } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
4143aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo    EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
4153aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo                     string_arg->GetLength() * sizeof(uint16_t)), 0);
4163aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo  } else {
4173aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo    bool equal = true;
4183aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo    for (int i = 0; i < string_arg->GetLength(); ++i) {
4193aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo      if (string_arg->CharAt(i) != string_result->CharAt(i)) {
4203aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo        equal = false;
4213aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo        break;
4223aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo      }
4233aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo    }
4243aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo    EXPECT_EQ(equal, true);
4253aaa37bba53d6df0265793de48b4b0b57327e57ajessicahandojo  }
426400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
427400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
428400ce0087ed0a41f385b55d555afc4616166965aJeff Hao}
429400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
43085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// Tests the exceptions that should be checked before modifying the destination.
43185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// (Doesn't check the object vs primitive case ATM.)
43285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
43385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Thread* self = Thread::Current();
43485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ScopedObjectAccess soa(self);
43585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  JValue result;
43685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
43785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
43885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
43985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //       allocate.
44085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<2> hs_misc(self);
44185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::Class> object_class(
44285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
44385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
44485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<3> hs_data(self);
44585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
44685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
44785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
44885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
44985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::ObjectArray<mirror::Object>> array(
45085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
45185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
45285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
45385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
45485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
45585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
45685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
45785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
45885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
45985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  mirror::ObjectArray<mirror::Object>* class_as_array =
46085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get());
46185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0);
46285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0);
46385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
46485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
46585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe}
46685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
46785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
46885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Thread* self = Thread::Current();
46985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ScopedObjectAccess soa(self);
47085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  JValue result;
47185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
47285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
47385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<1> hs_object(self);
47485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::Class> object_class(
47585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
47685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
47785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
47885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
47985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
48085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
48185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
48285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
48385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
48485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
48585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
48685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
48785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
48885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
48985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
49085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
49185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(0));
49285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(1));
49385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(1));
49485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
49585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
49685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
49785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 false,
49885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
49985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
50085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
50185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
50285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
50385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 2,
50485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
50585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
50685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
50785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
50885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
50985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
51085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
51185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
51285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
51385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
51485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
51585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
51685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
51785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
51885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
51985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
52085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
52185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
52285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(0));
52385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(1));
52485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(2));
52585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
52685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
52785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
52885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 false,
52985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
53085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 mirror::String::GetJavaLangString(),
53185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
53285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
53385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
53485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
53585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
53685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
53785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
53885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
53985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
54085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,*,3] into [4,5,6] = [1,5,6] + exc
54185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
54285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
54385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
54485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::GetJavaLangString());
54585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
54685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
54785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
54885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
54985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
55085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
55185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
55285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
55385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(0));
55485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(1));
55585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(2));
55685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
55785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
55885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
55985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 true,
56085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
56185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 mirror::String::GetJavaLangString(),
56285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
56385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 0,
56485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
56585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 0,
56685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 3,
56785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
56885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
56985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
57085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
57185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe}
57285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
57313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
57413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  Thread* self = Thread::Current();
57513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ScopedObjectAccess soa(self);
57613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
57713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
57813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
57913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
58013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // suffixes).
58113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr const char* test_string = "-2147483646";
58213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr int32_t test_values[] = {
58313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe                6,
58413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe               46,
58513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe              646,
58613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe             3646,
58713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe            83646,
58813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe           483646,
58913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe          7483646,
59013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe         47483646,
59113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        147483646,
59213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe       2147483646,
59313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe      -2147483646
59413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  };
59513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
59613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  static_assert(arraysize(test_values) == 11U, "test_values");
59713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  CHECK_EQ(strlen(test_string), 11U);
59813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
59913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  for (size_t i = 0; i <= 10; ++i) {
60013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    const char* test_value = &test_string[10 - i];
60113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
60213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    StackHandleScope<1> hs_str(self);
60313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    Handle<mirror::String> h_str(
60413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
60513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_NE(h_str.Get(), nullptr);
60613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
60713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
60813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    tmp->SetVRegReference(0, h_str.Get());
60913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
61013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    JValue result;
61113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    UnstartedIntegerParseInt(self, tmp, &result, 0);
61213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
61313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
61413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    EXPECT_EQ(result.GetI(), test_values[i]);
61513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  }
61613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
61713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
61813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe}
61913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
62013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe// Right now the same as Integer.Parse
62113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas GampeTEST_F(UnstartedRuntimeTest, LongParseLongTest) {
62213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  Thread* self = Thread::Current();
62313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ScopedObjectAccess soa(self);
62413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
62513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
62613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
62713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
62813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  // suffixes).
62913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr const char* test_string = "-2147483646";
63013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  constexpr int64_t test_values[] = {
63113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe                6,
63213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe               46,
63313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe              646,
63413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe             3646,
63513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe            83646,
63613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe           483646,
63713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe          7483646,
63813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe         47483646,
63913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        147483646,
64013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe       2147483646,
64113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe      -2147483646
64213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  };
64313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
64413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  static_assert(arraysize(test_values) == 11U, "test_values");
64513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  CHECK_EQ(strlen(test_string), 11U);
64613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
64713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  for (size_t i = 0; i <= 10; ++i) {
64813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    const char* test_value = &test_string[10 - i];
64913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
65013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    StackHandleScope<1> hs_str(self);
65113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    Handle<mirror::String> h_str(
65213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe        hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
65313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_NE(h_str.Get(), nullptr);
65413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
65513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
65613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    tmp->SetVRegReference(0, h_str.Get());
65713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
65813fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    JValue result;
65913fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    UnstartedLongParseLong(self, tmp, &result, 0);
66013fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
66113fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    ASSERT_FALSE(self->IsExceptionPending());
66213fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe    EXPECT_EQ(result.GetJ(), test_values[i]);
66313fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  }
66413fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
66513fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
66613fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe}
66713fc1be0b92b48ebc8fa79e4aac66f01a59181d8Andreas Gampe
66889e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Ceil) {
66989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  Thread* self = Thread::Current();
67089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ScopedObjectAccess soa(self);
67189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
67289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
67389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
67489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double nan = std::numeric_limits<double>::quiet_NaN();
67589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double inf = std::numeric_limits<double>::infinity();
67689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
67789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
67889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double test_pairs[][2] = {
67989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.0, -0.0 },
68089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.0,  0.0 },
68189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.5, -0.0 },
68289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -1.0, -1.0 },
68389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.5,  1.0 },
68489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  1.0,  1.0 },
68589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  nan,  nan },
68689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  inf,  inf },
68789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -inf, -inf },
68889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld1,  ld1 },
68989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld2,  ld2 }
69089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  };
69189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
69289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));
69389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
69489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
69589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe}
69689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
69789e3b486167c58a3268cf963c56183cd7f478b3cAndreas GampeTEST_F(UnstartedRuntimeTest, Floor) {
69889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  Thread* self = Thread::Current();
69989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ScopedObjectAccess soa(self);
70089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
70189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
70289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
70389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double nan = std::numeric_limits<double>::quiet_NaN();
70489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double inf = std::numeric_limits<double>::infinity();
70589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
70689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
70789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  constexpr double test_pairs[][2] = {
70889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.0, -0.0 },
70989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.0,  0.0 },
71089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -0.5, -1.0 },
71189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -1.0, -1.0 },
71289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  0.5,  0.0 },
71389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  1.0,  1.0 },
71489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  nan,  nan },
71589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  inf,  inf },
71689e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      { -inf, -inf },
71789e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld1,  ld1 },
71889e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe      {  ld2,  ld2 }
71989e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  };
72089e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
72189e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));
72289e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
72389e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
72489e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe}
72589e3b486167c58a3268cf963c56183cd7f478b3cAndreas Gampe
7268ce9c30f5d7328579619eb7e26c5f041837984afAndreas GampeTEST_F(UnstartedRuntimeTest, ToLowerUpper) {
7278ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  Thread* self = Thread::Current();
7288ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  ScopedObjectAccess soa(self);
7298ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7308ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
7318ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7328ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  std::locale c_locale("C");
7338ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7348ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  // Check ASCII.
7358ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  for (uint32_t i = 0; i < 128; ++i) {
7368ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    bool c_upper = std::isupper(static_cast<char>(i), c_locale);
7378ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    bool c_lower = std::islower(static_cast<char>(i), c_locale);
7388ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    EXPECT_FALSE(c_upper && c_lower) << i;
7398ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7408ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    // Check toLowerCase.
7418ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    {
7428ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      JValue result;
7438ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7448ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
7458ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      ASSERT_FALSE(self->IsExceptionPending());
7468ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      uint32_t lower_result = static_cast<uint32_t>(result.GetI());
7478ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      if (c_lower) {
7488ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        EXPECT_EQ(i, lower_result);
7498ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      } else if (c_upper) {
7508ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
7518ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe                  lower_result);
7528ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      } else {
7538ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        EXPECT_EQ(i, lower_result);
7548ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      }
7558ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    }
7568ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7578ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    // Check toUpperCase.
7588ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    {
7598ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      JValue result2;
7608ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
7618ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
7628ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      ASSERT_FALSE(self->IsExceptionPending());
7638ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
7648ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      if (c_upper) {
7658ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        EXPECT_EQ(i, upper_result);
7668ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      } else if (c_lower) {
7678ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
7688ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe                  upper_result);
7698ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      } else {
7708ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe        EXPECT_EQ(i, upper_result);
7718ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      }
7728ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    }
7738ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  }
7748ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7758ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  // Check abort for other things. Can't test all.
7768ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7778ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  PrepareForAborts();
7788ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
7798ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  for (uint32_t i = 128; i < 256; ++i) {
7808ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    {
7818ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      JValue result;
7828ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
78316d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      Runtime::Current()->EnterTransactionMode();
7848ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
78516d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
7868ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      Runtime::Current()->ExitTransactionMode();
7878ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
7888ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    }
7898ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    {
7908ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      JValue result;
7918ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
79216d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      Runtime::Current()->EnterTransactionMode();
7938ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      UnstartedCharacterToUpperCase(self, tmp, &result, 0);
79416d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
7958ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      Runtime::Current()->ExitTransactionMode();
7968ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
7978ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    }
7988ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  }
7998ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
8008ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    {
8018ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      JValue result;
8028ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
80316d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      Runtime::Current()->EnterTransactionMode();
8048ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      UnstartedCharacterToLowerCase(self, tmp, &result, 0);
80516d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
8068ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      Runtime::Current()->ExitTransactionMode();
8078ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
8088ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    }
8098ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    {
8108ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      JValue result;
8118ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      tmp->SetVReg(0, static_cast<int32_t>(i));
81216d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      Runtime::Current()->EnterTransactionMode();
8138ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      UnstartedCharacterToUpperCase(self, tmp, &result, 0);
81416d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
8158ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      Runtime::Current()->ExitTransactionMode();
8168ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe      ASSERT_TRUE(self->IsExceptionPending());
8178ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe    }
8188ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  }
8198ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
8208ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
8218ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe}
8228ce9c30f5d7328579619eb7e26c5f041837984afAndreas Gampe
823b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas GampeTEST_F(UnstartedRuntimeTest, Sin) {
824b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  Thread* self = Thread::Current();
825b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ScopedObjectAccess soa(self);
826b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
827b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
828b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
829b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  // Test an important value, PI/6. That's the one we see in practice.
830b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
831b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
832b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
833b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  JValue result;
834b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  UnstartedMathSin(self, tmp, &result, 0);
835b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
836b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
837b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
838b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
839b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
840b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe}
841b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
842b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas GampeTEST_F(UnstartedRuntimeTest, Cos) {
843b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  Thread* self = Thread::Current();
844b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ScopedObjectAccess soa(self);
845b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
846b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
847b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
848b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  // Test an important value, PI/6. That's the one we see in practice.
849b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
850b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
851b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
852b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  JValue result;
853b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  UnstartedMathCos(self, tmp, &result, 0);
854b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
855b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
856b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
857b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
858b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
859b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe}
860b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
861b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas GampeTEST_F(UnstartedRuntimeTest, Pow) {
862b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe  // Valgrind seems to get this wrong, actually. Disable for valgrind.
863b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe  if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
864b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe    return;
865b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe  }
866b6795157fd010375ca646ea95e972b616b4aeeafAndreas Gampe
867b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  Thread* self = Thread::Current();
868b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ScopedObjectAccess soa(self);
869b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
870b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
871b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
872b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  // Test an important pair.
873b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
874b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
875b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
876b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
877b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
878b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
879b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  JValue result;
880b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  UnstartedMathPow(self, tmp, &result, 0);
881b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
882b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
883b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
884b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
885b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
886b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe}
887b8a00f95e93eb0225e86dad582387f1cc69e7df6Andreas Gampe
888ae78c2643375c7536affcec318a60d13d430f181Andreas GampeTEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
889ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Thread* self = Thread::Current();
890ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ScopedObjectAccess soa(self);
891ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
892ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  JValue result;
893ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
894ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
895ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  mirror::Class* class_klass = mirror::Class::GetJavaLangClass();
896ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  shadow_frame->SetVRegReference(0, class_klass);
897ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
898ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  EXPECT_EQ(result.GetZ(), 0);
899ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
900ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  jobject class_loader = LoadDex("Nested");
901ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  StackHandleScope<1> hs(soa.Self());
902ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Handle<mirror::ClassLoader> loader(
903ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe      hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
904ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  mirror::Class* c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
905ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ASSERT_TRUE(c != nullptr);
906ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  shadow_frame->SetVRegReference(0, c);
907ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
908ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  EXPECT_EQ(result.GetZ(), 1);
909ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
910ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
911ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe}
912ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
913ae78c2643375c7536affcec318a60d13d430f181Andreas GampeTEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
914ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Thread* self = Thread::Current();
915ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ScopedObjectAccess soa(self);
916ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
917ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  JValue result;
918ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
919ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
920ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  jobject class_loader = LoadDex("Nested");
921ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  StackHandleScope<4> hs(self);
922ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Handle<mirror::ClassLoader> loader(
923ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe      hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
924ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
925ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Handle<mirror::Class> nested_klass(hs.NewHandle(
926ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe      class_linker_->FindClass(soa.Self(), "LNested;", loader)));
927ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Handle<mirror::Class> inner_klass(hs.NewHandle(
928ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe      class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
929ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  Handle<mirror::Class> anon_klass(hs.NewHandle(
930ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe      class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
931ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
932ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  shadow_frame->SetVRegReference(0, nested_klass.Get());
933ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
934ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  EXPECT_EQ(result.GetL(), nullptr);
935ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
936ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  shadow_frame->SetVRegReference(0, inner_klass.Get());
937ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
938ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  EXPECT_EQ(result.GetL(), nested_klass.Get());
939ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
940ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  shadow_frame->SetVRegReference(0, anon_klass.Get());
941ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
942ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  EXPECT_EQ(result.GetL(), nullptr);
943ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
944ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
945ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe}
946ae78c2643375c7536affcec318a60d13d430f181Andreas Gampe
9473d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas GampeTEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
9483d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  Thread* self = Thread::Current();
9493d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ScopedObjectAccess soa(self);
9503d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9513d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  JValue result;
9523d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
9533d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9543d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  StackHandleScope<1> hs(self);
9553d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
9563d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9573d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  // Positive test. See that We get something for float conversion.
9583d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  {
9593d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    Handle<mirror::Class> floating_decimal = hs.NewHandle(
9603d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe        class_linker->FindClass(self,
9613d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe                                "Lsun/misc/FloatingDecimal;",
9623d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe                                ScopedNullHandle<mirror::ClassLoader>()));
963fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe    ASSERT_TRUE(floating_decimal != nullptr);
9643d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
9653d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
966ba118827465d12177f3996e50133960087b1c916Vladimir Marko    ArtMethod* caller_method = floating_decimal->FindClassMethod(
9673d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe        "getBinaryToASCIIBuffer",
9683d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe        "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
9693d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe        class_linker->GetImagePointerSize());
9703d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
9713d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ASSERT_TRUE(caller_method != nullptr);
972ba118827465d12177f3996e50133960087b1c916Vladimir Marko    ASSERT_TRUE(caller_method->IsDirect());
973ba118827465d12177f3996e50133960087b1c916Vladimir Marko    ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
9743d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
9753d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    shadow_frame->SetLink(caller_frame);
9763d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9773d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
9783d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    EXPECT_TRUE(result.GetL() != nullptr);
9793d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    EXPECT_FALSE(self->IsExceptionPending());
9803d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9813d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
9823d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  }
9833d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9843d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  // Negative test.
9853d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  PrepareForAborts();
9863d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
9873d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  {
9883d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    // Just use a method in Class.
9893d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
9903d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ArtMethod* caller_method =
9913d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe        &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
9923d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
9933d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    shadow_frame->SetLink(caller_frame);
9943d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
99516d1dd86dca33520b44d9802695e19d3b658af3eChang Xing    Runtime::Current()->EnterTransactionMode();
9963d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
99716d1dd86dca33520b44d9802695e19d3b658af3eChang Xing    ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
9983d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    Runtime::Current()->ExitTransactionMode();
9993d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ASSERT_TRUE(self->IsExceptionPending());
10003d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    self->ClearException();
10013d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10023d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe    ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
10033d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  }
10043d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10053d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
10063d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe}
10073d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10083d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas GampeTEST_F(UnstartedRuntimeTest, FloatConversion) {
10093d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  Thread* self = Thread::Current();
10103d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ScopedObjectAccess soa(self);
10113d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10123d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  StackHandleScope<1> hs(self);
10133d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
10143d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  Handle<mirror::Class> double_class = hs.NewHandle(
10153d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe          class_linker->FindClass(self,
10163d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe                                  "Ljava/lang/Double;",
10173d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe                                  ScopedNullHandle<mirror::ClassLoader>()));
1018fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe  ASSERT_TRUE(double_class != nullptr);
10193d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
10203d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
1021ba118827465d12177f3996e50133960087b1c916Vladimir Marko  ArtMethod* method = double_class->FindClassMethod("toString",
1022ba118827465d12177f3996e50133960087b1c916Vladimir Marko                                                    "(D)Ljava/lang/String;",
1023ba118827465d12177f3996e50133960087b1c916Vladimir Marko                                                    class_linker->GetImagePointerSize());
10243d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ASSERT_TRUE(method != nullptr);
1025ba118827465d12177f3996e50133960087b1c916Vladimir Marko  ASSERT_TRUE(method->IsDirect());
1026ba118827465d12177f3996e50133960087b1c916Vladimir Marko  ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
10273d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10283d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  // create instruction data for invoke-direct {v0, v1} of method with fake index
10293d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
10303d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  const Instruction* inst = Instruction::At(inst_data);
10313d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10323d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  JValue result;
10333d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
10343d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  shadow_frame->SetVRegDouble(0, 1.23);
10353d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
10363d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL());
10373d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ASSERT_TRUE(string_result != nullptr);
10383d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10393d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  std::string mod_utf = string_result->ToModifiedUtf8();
10403d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  EXPECT_EQ("1.23", mod_utf);
10413d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
10423d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
10433d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe}
10443d2fcaae4145a50e4d7460d8ce3caf97eb825a08Andreas Gampe
1045bad529da18122c7044fbfd7d56153535d34367b1Andreas GampeTEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1046bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  Thread* self = Thread::Current();
1047bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ScopedObjectAccess soa(self);
1048bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1049bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  JValue result;
1050bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1051bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1052bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  StackHandleScope<1> hs(self);
1053bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1054bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  Handle<mirror::Class> thread_class = hs.NewHandle(
1055bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe      class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1056bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ASSERT_TRUE(thread_class.Get() != nullptr);
1057bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1058bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1059bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1060bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  // be recreated at runtime).
1061bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  PrepareForAborts();
1062bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1063bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  {
106416d1dd86dca33520b44d9802695e19d3b658af3eChang Xing    Runtime::Current()->EnterTransactionMode();
1065bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe    UnstartedThreadCurrentThread(self, shadow_frame, &result, 0);
106616d1dd86dca33520b44d9802695e19d3b658af3eChang Xing    ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
1067bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe    Runtime::Current()->ExitTransactionMode();
1068bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe    ASSERT_TRUE(self->IsExceptionPending());
1069bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe    self->ClearException();
1070bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  }
1071bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1072bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1073bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe}
1074bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1075bad529da18122c7044fbfd7d56153535d34367b1Andreas GampeTEST_F(UnstartedRuntimeTest, LogManager) {
1076bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  Thread* self = Thread::Current();
1077bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ScopedObjectAccess soa(self);
1078bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
1079bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  StackHandleScope<1> hs(self);
1080bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1081bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  Handle<mirror::Class> log_manager_class = hs.NewHandle(
10829486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe      class_linker->FindClass(self,
10839486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe                              "Ljava/util/logging/LogManager;",
10849486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe                              ScopedNullHandle<mirror::ClassLoader>()));
1085bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ASSERT_TRUE(log_manager_class.Get() != nullptr);
1086bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe  ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1087bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe}
1088bad529da18122c7044fbfd7d56153535d34367b1Andreas Gampe
108947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampeclass UnstartedClassForNameTest : public UnstartedRuntimeTest {
109047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe public:
109147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  template <typename T>
109247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  void RunTest(T& runner, bool in_transaction, bool should_succeed) {
109347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    Thread* self = Thread::Current();
109447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    ScopedObjectAccess soa(self);
109547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
109647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    // Ensure that Class is initialized.
109747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    {
109847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
109947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      StackHandleScope<1> hs(self);
110047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass());
110147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
110247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    }
110347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
110447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    // A selection of classes from different core classpath components.
110547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    constexpr const char* kTestCases[] = {
110647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        "java.net.CookieManager",  // From libcore.
110747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        "dalvik.system.ClassExt",  // From libart.
110847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    };
110947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
111047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    if (in_transaction) {
111147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      // For transaction mode, we cannot load any classes, as the pre-fence initialization of
111247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      // classes isn't transactional. Load them ahead of time.
111347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
111447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      for (const char* name : kTestCases) {
111547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        class_linker->FindClass(self,
111647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                DotToDescriptor(name).c_str(),
111747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                ScopedNullHandle<mirror::ClassLoader>());
111847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
111947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      }
112047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    }
112147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
112247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    if (!should_succeed) {
112347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      // Negative test. In general, currentThread should fail (as we should not leak a peer that will
112447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      // be recreated at runtime).
112547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      PrepareForAborts();
112647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    }
112747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
112847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    JValue result;
112947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
113047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
113147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    for (const char* name : kTestCases) {
113247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name);
113347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(name_string != nullptr);
113447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
113547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      if (in_transaction) {
113616d1dd86dca33520b44d9802695e19d3b658af3eChang Xing        Runtime::Current()->EnterTransactionMode();
113747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      }
113847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(!self->IsExceptionPending());
113947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
114047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      runner(self, shadow_frame, name_string, &result);
114147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
114247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      if (should_succeed) {
114347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
114447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        CHECK(result.GetL() != nullptr) << name;
114547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      } else {
114647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        CHECK(self->IsExceptionPending()) << name;
114747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        if (in_transaction) {
114816d1dd86dca33520b44d9802695e19d3b658af3eChang Xing          ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
114947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        }
115047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe        self->ClearException();
115147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      }
115216d1dd86dca33520b44d9802695e19d3b658af3eChang Xing
115316d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      if (in_transaction) {
115416d1dd86dca33520b44d9802695e19d3b658af3eChang Xing        Runtime::Current()->ExitTransactionMode();
115516d1dd86dca33520b44d9802695e19d3b658af3eChang Xing      }
115647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    }
115747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
115847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
115947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  }
116047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
116147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
116247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    Thread* self = Thread::Current();
116347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    StackHandleScope<2> hs(self);
116447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
116547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
116647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    {
116747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
116847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
116947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
117047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      Handle<mirror::Class> boot_cp_class = hs.NewHandle(
117147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe          class_linker->FindClass(self,
117247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                  "Ljava/lang/BootClassLoader;",
117347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                  ScopedNullHandle<mirror::ClassLoader>()));
117447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(boot_cp_class != nullptr);
117547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
117647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
117747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
117847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(boot_cp != nullptr);
117947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
1180ba118827465d12177f3996e50133960087b1c916Vladimir Marko      ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1181ba118827465d12177f3996e50133960087b1c916Vladimir Marko          "()V", class_linker->GetImagePointerSize());
118247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(boot_cp_init != nullptr);
118347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
118447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      JValue result;
118547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0);
118647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      shadow_frame->SetVRegReference(0, boot_cp.Get());
118747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
118847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      // create instruction data for invoke-direct {v0} of method with fake index
118947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
119047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      const Instruction* inst = Instruction::At(inst_data);
119147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
119247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      interpreter::DoCall<false, false>(boot_cp_init,
119347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                        self,
119447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                        *shadow_frame,
119547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                        inst,
119647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                        inst_data[0],
119747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe                                        &result);
119847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      CHECK(!self->IsExceptionPending());
119947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
120047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
120147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    }
120247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
120347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    return boot_cp.Get();
120447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  }
120547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe};
120647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
120747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForName) {
120847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
120947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
121047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(0, name);
121147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    UnstartedClassForName(self, shadow_frame, result, 0);
121247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  };
121347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  RunTest(runner, false, true);
121447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe}
121547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
121647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLong) {
121747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
121847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe            REQUIRES_SHARED(Locks::mutator_lock_) {
121947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(0, name);
122047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVReg(1, 0);
122147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(2, nullptr);
122247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    UnstartedClassForNameLong(self, shadow_frame, result, 0);
122347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  };
122447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  RunTest(runner, false, true);
122547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe}
122647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
122747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
122847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  Thread* self = Thread::Current();
122947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  ScopedObjectAccess soa(self);
123047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
123147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  StackHandleScope<1> hs(self);
123247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
123347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
123447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
123547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
123647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(0, name);
123747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVReg(1, 0);
123847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(2, boot_cp.Get());
123947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    UnstartedClassForNameLong(th, shadow_frame, result, 0);
124047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  };
124147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  RunTest(runner, false, true);
124247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe}
124347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
124447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
124547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  Thread* self = Thread::Current();
124647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  ScopedObjectAccess soa(self);
124747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
124847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  StackHandleScope<1> hs(self);
124947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
125047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
125147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
125247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
125347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(0, name);
125447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVReg(1, 0);
125547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(2, boot_cp.Get());
125647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    UnstartedClassForNameLong(th, shadow_frame, result, 0);
125747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  };
125847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  RunTest(runner, true, true);
125947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe}
126047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
126147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas GampeTEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
126247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  Thread* self = Thread::Current();
126347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  ScopedObjectAccess soa(self);
126447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
126547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  StackHandleScope<2> hs(self);
126647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
126747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
126847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  ASSERT_TRUE(path_jobj != nullptr);
126947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
127047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      self->DecodeJObject(path_jobj)->AsClassLoader());
127147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
127247de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
127347de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
127447de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(0, name);
127547de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVReg(1, 0);
127647de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    shadow_frame->SetVRegReference(2, path_cp.Get());
127747de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe    UnstartedClassForNameLong(th, shadow_frame, result, 0);
127847de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  };
127947de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe  RunTest(runner, true, false);
128047de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe}
128147de0fad87b5e9a02b1fdde124ff32247f0b477eAndreas Gampe
12829486a16180466e32aa8a98927030aff9fbdce189Andreas GampeTEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
12839486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  Thread* self = Thread::Current();
12849486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ScopedObjectAccess soa(self);
12859486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe
12869486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  StackHandleScope<1> hs(self);
12879486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
12889486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  Handle<mirror::Class> list_class = hs.NewHandle(
12899486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe      class_linker->FindClass(self,
12909486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe                              "Ljava/util/List;",
12919486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe                              ScopedNullHandle<mirror::ClassLoader>()));
12929486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ASSERT_TRUE(list_class.Get() != nullptr);
12939486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
12949486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe
12959486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  JValue result;
12969486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
12979486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe
12989486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  shadow_frame->SetVRegReference(0, list_class.Get());
12999486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0);
13009486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ASSERT_TRUE(result.GetL() != nullptr);
13019486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ASSERT_FALSE(self->IsExceptionPending());
13029486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe
13039486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
13049486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe
13059486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ASSERT_TRUE(result.GetL()->IsObjectArray());
13069486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ObjPtr<mirror::ObjectArray<mirror::Object>> array =
13079486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe      result.GetL()->AsObjectArray<mirror::Object>();
13089486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  std::ostringstream oss;
13099486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  for (int32_t i = 0; i != array->GetLength(); ++i) {
13109486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe    ObjPtr<mirror::Object> elem = array->Get(i);
13119486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe    ASSERT_TRUE(elem != nullptr);
13129486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe    ASSERT_TRUE(elem->IsString());
13139486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe    oss << elem->AsString()->ToModifiedUtf8();
13149486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  }
13159486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  std::string output_string = oss.str();
13169486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe  ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
13179486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe}
13189486a16180466e32aa8a98927030aff9fbdce189Andreas Gampe
131985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas GampeTEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
132085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  Thread* self = Thread::Current();
132185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ScopedObjectAccess soa(self);
132285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
132385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  StackHandleScope<4> hs(self);
132485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
132585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
132685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // Get Throwable.
132785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable());
132885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
132985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
133085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // Get an input object.
133185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
133285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
133385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // Find the constructor.
1334ba118827465d12177f3996e50133960087b1c916Vladimir Marko  ArtMethod* throw_cons = throw_class->FindConstructor(
1335ba118827465d12177f3996e50133960087b1c916Vladimir Marko      "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
133685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_TRUE(throw_cons != nullptr);
1337fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing  Handle<mirror::Constructor> cons;
1338fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing  if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1339fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing     cons = hs.NewHandle(
1340fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing        mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1341fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing    ASSERT_TRUE(cons != nullptr);
1342fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing  } else {
1343fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing    cons = hs.NewHandle(
1344fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing        mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1345fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing    ASSERT_TRUE(cons != nullptr);
1346fef27c271e536f84e2d44fd0730b9fb329296376Chang Xing  }
134785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
134885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
1349c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe      mirror::ObjectArray<mirror::Object>::Alloc(
1350c6ea7d00ad069a2736f603daa3d8eaa9a1f8ea11Andreas Gampe          self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1));
135185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_TRUE(args != nullptr);
135285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  args->Set(0, input.Get());
135385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
135485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // OK, we're ready now.
135585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  JValue result;
135685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
135785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  shadow_frame->SetVRegReference(0, cons.Get());
135885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  shadow_frame->SetVRegReference(1, args.Get());
135985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0);
136085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
136185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_TRUE(result.GetL() != nullptr);
136285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_FALSE(self->IsExceptionPending());
136385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
136485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // Should be a new object.
136585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_NE(result.GetL(), input.Get());
136685bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // Should be a String.
136785bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass());
136885bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  // Should have the right string.
136985bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ObjPtr<mirror::String> result_msg =
137085bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe      reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
137185bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  EXPECT_EQ(input.Get(), result_msg.Ptr());
137285bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
137385bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
137485bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe}
137585bef7ea31ac8ad90f97b20c3c391da99c4fb8a0Andreas Gampe
1376ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas GeoffrayTEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1377ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  Thread* self = Thread::Current();
1378ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  ScopedObjectAccess soa(self);
1379ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1380ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray
1381ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  JValue result;
1382ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1383ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray
1384ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  EXPECT_EQ(0, result.GetI());
1385ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  ASSERT_FALSE(self->IsExceptionPending());
1386ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray
1387ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
1388ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  tmp->SetVRegReference(0, str.Ptr());
1389ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1390ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  EXPECT_NE(0, result.GetI());
1391ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1392ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  ASSERT_FALSE(self->IsExceptionPending());
1393ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray
1394ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray  ShadowFrame::DeleteDeoptimizedFrame(tmp);
1395ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray}
1396ece2f7c2644062cb39ad9a62cc19278398deec6bNicolas Geoffray
1397799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}  // namespace interpreter
1398799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}  // namespace art
1399