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