unstarted_runtime_test.cc revision 85a098af5fc8d2dd0e39d61c9f93fc6257d631c5
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
19799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "class_linker.h"
20799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "common_runtime_test.h"
21400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "dex_instruction.h"
22799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle.h"
23799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "handle_scope-inl.h"
24400ce0087ed0a41f385b55d555afc4616166965aJeff Hao#include "interpreter/interpreter_common.h"
25799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/class_loader.h"
26799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "mirror/string-inl.h"
27799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "runtime.h"
28799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "scoped_thread_state_change.h"
29799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "thread.h"
30799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
31799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace art {
32799681b176ad25437ce2849639f54f610dcbf684Andreas Gampenamespace interpreter {
33799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
34799681b176ad25437ce2849639f54f610dcbf684Andreas Gampeclass UnstartedRuntimeTest : public CommonRuntimeTest {
35799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe protected:
36799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
37799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // test friends.
38799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
39799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Methods that intercept available libcore implementations.
40799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#define UNSTARTED_DIRECT(Name, SigIgnored)                 \
41799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  static void Unstarted ## Name(Thread* self,              \
42799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                ShadowFrame* shadow_frame, \
43799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                JValue* result,            \
44799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                size_t arg_offset)         \
4590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {        \
46799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
47799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
48799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h"
49799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
50799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST
51799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST
52799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_DIRECT
53799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
54799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // Methods that are native.
55e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#define UNSTARTED_JNI(Name, SigIgnored)                       \
56799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  static void UnstartedJNI ## Name(Thread* self,              \
57e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                   ArtMethod* method,         \
58799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   mirror::Object* receiver,  \
59799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   uint32_t* args,            \
60799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe                                   JValue* result)            \
6190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {           \
62799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
63799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
64799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#include "unstarted_runtime_list.h"
65799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
66799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_DIRECT_LIST
67799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_RUNTIME_JNI_LIST
68799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe#undef UNSTARTED_JNI
6985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
7085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Helpers for ArrayCopy.
7185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //
7285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
7385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //       of three everywhere. That is enough to test all cases.
7485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
7585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  static mirror::ObjectArray<mirror::Object>* CreateObjectArray(
7685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      Thread* self,
7785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      mirror::Class* component_type,
7885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      const StackHandleScope<3>& data)
7985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
8085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Runtime* runtime = Runtime::Current();
8185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    mirror::Class* array_type = runtime->GetClassLinker()->FindArrayClass(self, &component_type);
8285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK(array_type != nullptr);
8385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    mirror::ObjectArray<mirror::Object>* result =
8485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
8585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK(result != nullptr);
8685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    for (size_t i = 0; i < 3; ++i) {
8785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      result->Set(static_cast<int32_t>(i), data.GetReference(i));
8885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      CHECK(!self->IsExceptionPending());
8985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
9085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    return result;
9185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
9285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
9385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array,
9485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                               const StackHandleScope<3>& data)
9585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
9685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK_EQ(array->GetLength(), 3);
9785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CHECK_EQ(data.NumberOfReferences(), 3U);
9885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    for (size_t i = 0; i < 3; ++i) {
9985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
10085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
10185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
10285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
10385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  void RunArrayCopy(Thread* self,
10485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    ShadowFrame* tmp,
10585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    bool expect_exception,
10685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::ObjectArray<mirror::Object>* src,
10785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t src_pos,
10885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::ObjectArray<mirror::Object>* dst,
10985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t dst_pos,
11085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t length)
11185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
11285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    JValue result;
11385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVRegReference(0, src);
11485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(1, src_pos);
11585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVRegReference(2, dst);
11685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(3, dst_pos);
11785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    tmp->SetVReg(4, length);
11885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    UnstartedSystemArraycopy(self, tmp, &result, 0);
11985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    bool exception_pending = self->IsExceptionPending();
12085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    EXPECT_EQ(exception_pending, expect_exception);
12185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    if (exception_pending) {
12285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      self->ClearException();
12385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    }
12485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
12585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
12685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  void RunArrayCopy(Thread* self,
12785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    ShadowFrame* tmp,
12885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    bool expect_exception,
12985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::Class* src_component_class,
13085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    mirror::Class* dst_component_class,
13185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& src_data,
13285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t src_pos,
13385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& dst_data,
13485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t dst_pos,
13585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    int32_t length,
13685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                    const StackHandleScope<3>& expected_result)
13785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      SHARED_REQUIRES(Locks::mutator_lock_) {
13885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_misc(self);
13985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
14085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
14185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::ObjectArray<mirror::Object>> src_handle(
14285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
14385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
14485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
14585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe        hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
14685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
14785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
14885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
14985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 expect_exception,
15085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 src_handle.Get(),
15185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 src_pos,
15285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 dst_handle.Get(),
15385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 dst_pos,
15485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 length);
15585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    CheckObjectArray(dst_handle.Get(), expected_result);
15685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
157799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe};
158799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
159799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
160799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
161799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
162799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
163799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
164799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
165799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
166799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
167799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
168799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
169799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
170799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < kBaseLen; ++i) {
171799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
172799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
173799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekByte(self, tmp, &result, 0);
174799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
175799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
176799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
177799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
178799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
179799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
180799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
181799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
182799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
183799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
184799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
185799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
186799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
187799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
188799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
189799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
190799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
191799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
192799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int16_t);
193799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
194799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
195799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
196799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekShort(self, tmp, &result, 0);
197799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
198799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int16_t unaligned_short __attribute__ ((aligned (1)));
199799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
200799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetS(), *short_ptr);
201799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
202799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
203799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
204799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
205799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
206799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
207799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
208799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
209799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
210799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
211799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
212799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
213799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
214799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
215799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
216799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
217799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int32_t);
218799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
219799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
220799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
221799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekInt(self, tmp, &result, 0);
222799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
223799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int32_t unaligned_int __attribute__ ((aligned (1)));
224799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
225799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetI(), *int_ptr);
226799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
227799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
228799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
229799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
230799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
231799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
232799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
233799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
234799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
235799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const uint8_t base_array[] = "abcdefghijklmnop";
236799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
237799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  const uint8_t* base_ptr = base_array;
238799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
239799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
240799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
241799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
242799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t adjusted_length = kBaseLen - sizeof(int64_t);
243799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < adjusted_length; ++i) {
244799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
245799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
246799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedMemoryPeekLong(self, tmp, &result, 0);
247799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
248799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    typedef int64_t unaligned_long __attribute__ ((aligned (1)));
249799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
250799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetJ(), *long_ptr);
251799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
252799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
253799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
254799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
255799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
256799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
257799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
258799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
259799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
260799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  StackHandleScope<2> hs(self);
261799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // TODO: Actual UTF.
262799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const char base_string[] = "abcdefghijklmnop";
263799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Handle<mirror::String> h_test_string(hs.NewHandle(
264799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      mirror::String::AllocFromModifiedUtf8(self, base_string)));
265799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
266799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Handle<mirror::CharArray> h_char_array(hs.NewHandle(
267799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      mirror::CharArray::Alloc(self, kBaseLen)));
268799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // A buffer so we can make sure we only modify the elements targetted.
269799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  uint16_t buf[kBaseLen];
270799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
271799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
272799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
273799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
274799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
275799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    for (int32_t count = 0; count <= kBaseLen; ++count) {
276799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
277799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        // Only do it when in bounds.
278799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
279799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVRegReference(0, h_test_string.Get());
280799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(1, start_index);
281799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(2, count);
282799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVRegReference(3, h_char_array.Get());
283799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          tmp->SetVReg(3, trg_offset);
284799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
285799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Copy the char_array into buf.
286799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
287799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
288799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          UnstartedStringCharAt(self, tmp, &result, 0);
289799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
290799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          uint16_t* data = h_char_array->GetData();
291799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
292799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          bool success = true;
293799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
294799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // First segment should be unchanged.
295799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = 0; i < trg_offset; ++i) {
296799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i]);
297799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
298799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Second segment should be a copy.
299799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
300799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i - trg_offset + start_index]);
301799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
302799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          // Third segment should be unchanged.
303799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
304799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe            success = success && (data[i] == buf[i]);
305799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          }
306799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
307799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe          EXPECT_TRUE(success);
308799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe        }
309799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      }
310799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    }
311799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
312799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
313799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
314799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
315799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
316799681b176ad25437ce2849639f54f610dcbf684Andreas GampeTEST_F(UnstartedRuntimeTest, StringCharAt) {
317799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  Thread* self = Thread::Current();
318799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
319799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ScopedObjectAccess soa(self);
320799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  // TODO: Actual UTF.
321799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  constexpr const char* base_string = "abcdefghijklmnop";
322799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  int32_t base_len = static_cast<int32_t>(strlen(base_string));
323799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
324799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
325799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  JValue result;
326799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
327799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
328799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  for (int32_t i = 0; i < base_len; ++i) {
329799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVRegReference(0, test_string);
330799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    tmp->SetVReg(1, i);
331799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
332799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedStringCharAt(self, tmp, &result, 0);
333799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
334799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    EXPECT_EQ(result.GetI(), base_string[i]);
335799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  }
336799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
337799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
338799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}
339799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe
340400ce0087ed0a41f385b55d555afc4616166965aJeff HaoTEST_F(UnstartedRuntimeTest, StringInit) {
341400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  Thread* self = Thread::Current();
342400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ScopedObjectAccess soa(self);
343400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::Class* klass = mirror::String::GetJavaLangString();
344e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V",
345e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                                      sizeof(void*));
346400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
347400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  // create instruction data for invoke-direct {v0, v1} of method with fake index
348400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
349400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  const Instruction* inst = Instruction::At(inst_data);
350400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
351400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  JValue result;
352400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
353400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  const char* base_string = "hello_world";
354400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string);
355400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, "");
356400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  shadow_frame->SetVRegReference(0, reference_empty_string);
357400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  shadow_frame->SetVRegReference(1, string_arg);
358400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
359400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
360400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL());
361400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
362400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
363400ce0087ed0a41f385b55d555afc4616166965aJeff Hao                   string_arg->GetLength() * sizeof(uint16_t)), 0);
364400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
365400ce0087ed0a41f385b55d555afc4616166965aJeff Hao  ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
366400ce0087ed0a41f385b55d555afc4616166965aJeff Hao}
367400ce0087ed0a41f385b55d555afc4616166965aJeff Hao
36885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// Tests the exceptions that should be checked before modifying the destination.
36985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe// (Doesn't check the object vs primitive case ATM.)
37085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
37185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Thread* self = Thread::Current();
37285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ScopedObjectAccess soa(self);
37385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  JValue result;
37485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
37585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
37685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
37785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  //       allocate.
37885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<2> hs_misc(self);
37985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::Class> object_class(
38085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
38185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
38285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<3> hs_data(self);
38385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
38485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
38585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
38685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
38785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::ObjectArray<mirror::Object>> array(
38885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
38985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
39085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
39185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
39285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
39385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
39485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
39585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
39685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
39785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  mirror::ObjectArray<mirror::Object>* class_as_array =
39885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get());
39985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0);
40085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0);
40185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
40285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
40385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe}
40485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
40585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas GampeTEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
40685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Thread* self = Thread::Current();
40785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ScopedObjectAccess soa(self);
40885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  JValue result;
40985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
41085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
41185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  StackHandleScope<1> hs_object(self);
41285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  Handle<mirror::Class> object_class(
41385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe      hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
41485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
41585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
41685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
41785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
41885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
41985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
42085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
42185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
42285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
42385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
42485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
42585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
42685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
42785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
42885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
42985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(0));
43085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(1));
43185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(1));
43285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
43385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
43485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
43585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 false,
43685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
43785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
43885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
43985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
44085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
44185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 2,
44285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
44385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
44485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
44585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
44685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
44785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
44885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
44985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
45085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
45185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
45285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
45385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
45485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
45585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
45685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
45785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
45885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
45985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
46085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(0));
46185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(1));
46285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(2));
46385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
46485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
46585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
46685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 false,
46785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
46885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 mirror::String::GetJavaLangString(),
46985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
47085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
47185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
47285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
47385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 1,
47485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
47585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
47685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
47785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // Simple test:
47885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  // [1,*,3] into [4,5,6] = [1,5,6] + exc
47985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  {
48085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_src(self);
48185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
48285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::GetJavaLangString());
48385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
48485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
48585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_dst(self);
48685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
48785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
48885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
48985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
49085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    StackHandleScope<3> hs_expected(self);
49185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_src.GetReference(0));
49285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(1));
49385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    hs_expected.NewHandle(hs_dst.GetReference(2));
49485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
49585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe    RunArrayCopy(self,
49685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 tmp,
49785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 true,
49885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 object_class.Get(),
49985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 mirror::String::GetJavaLangString(),
50085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_src,
50185a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 0,
50285a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_dst,
50385a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 0,
50485a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 3,
50585a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe                 hs_expected);
50685a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  }
50785a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
50885a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe  ShadowFrame::DeleteDeoptimizedFrame(tmp);
50985a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe}
51085a098af5fc8d2dd0e39d61c9f93fc6257d631c5Andreas Gampe
511799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}  // namespace interpreter
512799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe}  // namespace art
513