xref: /aosp_15_r20/art/runtime/interpreter/unstarted_runtime_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "unstarted_runtime_test.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <limits>
20*795d594fSAndroid Build Coastguard Worker #include <locale>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/memory_tool.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
25*795d594fSAndroid Build Coastguard Worker #include "class_linker.h"
26*795d594fSAndroid Build Coastguard Worker #include "class_root-inl.h"
27*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
28*795d594fSAndroid Build Coastguard Worker #include "common_throws.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex/descriptors_names.h"
30*795d594fSAndroid Build Coastguard Worker #include "dex/dex_instruction.h"
31*795d594fSAndroid Build Coastguard Worker #include "handle.h"
32*795d594fSAndroid Build Coastguard Worker #include "handle_scope-inl.h"
33*795d594fSAndroid Build Coastguard Worker #include "interpreter_common.h"
34*795d594fSAndroid Build Coastguard Worker #include "mirror/array-alloc-inl.h"
35*795d594fSAndroid Build Coastguard Worker #include "mirror/class-alloc-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "mirror/class_loader.h"
37*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h"
38*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-alloc-inl.h"
39*795d594fSAndroid Build Coastguard Worker #include "mirror/object_array-inl.h"
40*795d594fSAndroid Build Coastguard Worker #include "mirror/string-inl.h"
41*795d594fSAndroid Build Coastguard Worker #include "runtime.h"
42*795d594fSAndroid Build Coastguard Worker #include "runtime_intrinsics.h"
43*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
44*795d594fSAndroid Build Coastguard Worker #include "shadow_frame-inl.h"
45*795d594fSAndroid Build Coastguard Worker #include "thread.h"
46*795d594fSAndroid Build Coastguard Worker #include "unstarted_runtime_list.h"
47*795d594fSAndroid Build Coastguard Worker 
48*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
49*795d594fSAndroid Build Coastguard Worker namespace interpreter {
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker class UnstartedRuntimeTest : public UnstartedRuntimeTestBase {
52*795d594fSAndroid Build Coastguard Worker  protected:
53*795d594fSAndroid Build Coastguard Worker   // Helpers for ArrayCopy.
54*795d594fSAndroid Build Coastguard Worker   //
55*795d594fSAndroid Build Coastguard Worker   // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
56*795d594fSAndroid Build Coastguard Worker   //       of three everywhere. That is enough to test all cases.
57*795d594fSAndroid Build Coastguard Worker 
CreateObjectArray(Thread * self,ObjPtr<mirror::Class> component_type,const StackHandleScope<3> & data)58*795d594fSAndroid Build Coastguard Worker   static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
59*795d594fSAndroid Build Coastguard Worker       Thread* self,
60*795d594fSAndroid Build Coastguard Worker       ObjPtr<mirror::Class> component_type,
61*795d594fSAndroid Build Coastguard Worker       const StackHandleScope<3>& data)
62*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
63*795d594fSAndroid Build Coastguard Worker     Runtime* runtime = Runtime::Current();
64*795d594fSAndroid Build Coastguard Worker     ObjPtr<mirror::Class> array_type =
65*795d594fSAndroid Build Coastguard Worker         runtime->GetClassLinker()->FindArrayClass(self, component_type);
66*795d594fSAndroid Build Coastguard Worker     CHECK(array_type != nullptr);
67*795d594fSAndroid Build Coastguard Worker     ObjPtr<mirror::ObjectArray<mirror::Object>> result =
68*795d594fSAndroid Build Coastguard Worker         mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
69*795d594fSAndroid Build Coastguard Worker     CHECK(result != nullptr);
70*795d594fSAndroid Build Coastguard Worker     for (size_t i = 0; i < 3; ++i) {
71*795d594fSAndroid Build Coastguard Worker       result->Set(static_cast<int32_t>(i), data.GetReference(i));
72*795d594fSAndroid Build Coastguard Worker       CHECK(!self->IsExceptionPending());
73*795d594fSAndroid Build Coastguard Worker     }
74*795d594fSAndroid Build Coastguard Worker     return result;
75*795d594fSAndroid Build Coastguard Worker   }
76*795d594fSAndroid Build Coastguard Worker 
CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,const StackHandleScope<3> & data)77*795d594fSAndroid Build Coastguard Worker   static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
78*795d594fSAndroid Build Coastguard Worker                                const StackHandleScope<3>& data)
79*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
80*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(array->GetLength(), 3);
81*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(data.Size(), 3U);
82*795d594fSAndroid Build Coastguard Worker     for (size_t i = 0; i < 3; ++i) {
83*795d594fSAndroid Build Coastguard Worker       EXPECT_OBJ_PTR_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
84*795d594fSAndroid Build Coastguard Worker     }
85*795d594fSAndroid Build Coastguard Worker   }
86*795d594fSAndroid Build Coastguard Worker 
RunArrayCopy(Thread * self,ShadowFrame * tmp,bool expect_exception,ObjPtr<mirror::ObjectArray<mirror::Object>> src,int32_t src_pos,ObjPtr<mirror::ObjectArray<mirror::Object>> dst,int32_t dst_pos,int32_t length)87*795d594fSAndroid Build Coastguard Worker   void RunArrayCopy(Thread* self,
88*795d594fSAndroid Build Coastguard Worker                     ShadowFrame* tmp,
89*795d594fSAndroid Build Coastguard Worker                     bool expect_exception,
90*795d594fSAndroid Build Coastguard Worker                     ObjPtr<mirror::ObjectArray<mirror::Object>> src,
91*795d594fSAndroid Build Coastguard Worker                     int32_t src_pos,
92*795d594fSAndroid Build Coastguard Worker                     ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
93*795d594fSAndroid Build Coastguard Worker                     int32_t dst_pos,
94*795d594fSAndroid Build Coastguard Worker                     int32_t length)
95*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
96*795d594fSAndroid Build Coastguard Worker     JValue result;
97*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegReference(0, src);
98*795d594fSAndroid Build Coastguard Worker     tmp->SetVReg(1, src_pos);
99*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegReference(2, dst);
100*795d594fSAndroid Build Coastguard Worker     tmp->SetVReg(3, dst_pos);
101*795d594fSAndroid Build Coastguard Worker     tmp->SetVReg(4, length);
102*795d594fSAndroid Build Coastguard Worker     UnstartedSystemArraycopy(self, tmp, &result, 0);
103*795d594fSAndroid Build Coastguard Worker     bool exception_pending = self->IsExceptionPending();
104*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(exception_pending, expect_exception);
105*795d594fSAndroid Build Coastguard Worker     if (exception_pending) {
106*795d594fSAndroid Build Coastguard Worker       self->ClearException();
107*795d594fSAndroid Build Coastguard Worker     }
108*795d594fSAndroid Build Coastguard Worker   }
109*795d594fSAndroid Build Coastguard Worker 
RunArrayCopy(Thread * self,ShadowFrame * tmp,bool expect_exception,ObjPtr<mirror::Class> src_component_class,ObjPtr<mirror::Class> dst_component_class,const StackHandleScope<3> & src_data,int32_t src_pos,const StackHandleScope<3> & dst_data,int32_t dst_pos,int32_t length,const StackHandleScope<3> & expected_result)110*795d594fSAndroid Build Coastguard Worker   void RunArrayCopy(Thread* self,
111*795d594fSAndroid Build Coastguard Worker                     ShadowFrame* tmp,
112*795d594fSAndroid Build Coastguard Worker                     bool expect_exception,
113*795d594fSAndroid Build Coastguard Worker                     ObjPtr<mirror::Class> src_component_class,
114*795d594fSAndroid Build Coastguard Worker                     ObjPtr<mirror::Class> dst_component_class,
115*795d594fSAndroid Build Coastguard Worker                     const StackHandleScope<3>& src_data,
116*795d594fSAndroid Build Coastguard Worker                     int32_t src_pos,
117*795d594fSAndroid Build Coastguard Worker                     const StackHandleScope<3>& dst_data,
118*795d594fSAndroid Build Coastguard Worker                     int32_t dst_pos,
119*795d594fSAndroid Build Coastguard Worker                     int32_t length,
120*795d594fSAndroid Build Coastguard Worker                     const StackHandleScope<3>& expected_result)
121*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
122*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_misc(self);
123*795d594fSAndroid Build Coastguard Worker     Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ObjectArray<mirror::Object>> src_handle(
126*795d594fSAndroid Build Coastguard Worker         hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker     Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
129*795d594fSAndroid Build Coastguard Worker         hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker     RunArrayCopy(self,
132*795d594fSAndroid Build Coastguard Worker                  tmp,
133*795d594fSAndroid Build Coastguard Worker                  expect_exception,
134*795d594fSAndroid Build Coastguard Worker                  src_handle.Get(),
135*795d594fSAndroid Build Coastguard Worker                  src_pos,
136*795d594fSAndroid Build Coastguard Worker                  dst_handle.Get(),
137*795d594fSAndroid Build Coastguard Worker                  dst_pos,
138*795d594fSAndroid Build Coastguard Worker                  length);
139*795d594fSAndroid Build Coastguard Worker     CheckObjectArray(dst_handle.Get(), expected_result);
140*795d594fSAndroid Build Coastguard Worker   }
141*795d594fSAndroid Build Coastguard Worker 
TestCeilFloor(bool ceil,Thread * self,ShadowFrame * tmp,double const test_pairs[][2],size_t num_pairs)142*795d594fSAndroid Build Coastguard Worker   void TestCeilFloor(bool ceil,
143*795d594fSAndroid Build Coastguard Worker                      Thread* self,
144*795d594fSAndroid Build Coastguard Worker                      ShadowFrame* tmp,
145*795d594fSAndroid Build Coastguard Worker                      double const test_pairs[][2],
146*795d594fSAndroid Build Coastguard Worker                      size_t num_pairs)
147*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
148*795d594fSAndroid Build Coastguard Worker     for (size_t i = 0; i < num_pairs; ++i) {
149*795d594fSAndroid Build Coastguard Worker       tmp->SetVRegDouble(0, test_pairs[i][0]);
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker       JValue result;
152*795d594fSAndroid Build Coastguard Worker       if (ceil) {
153*795d594fSAndroid Build Coastguard Worker         UnstartedMathCeil(self, tmp, &result, 0);
154*795d594fSAndroid Build Coastguard Worker       } else {
155*795d594fSAndroid Build Coastguard Worker         UnstartedMathFloor(self, tmp, &result, 0);
156*795d594fSAndroid Build Coastguard Worker       }
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker       ASSERT_FALSE(self->IsExceptionPending());
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker       // We want precise results.
161*795d594fSAndroid Build Coastguard Worker       int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
162*795d594fSAndroid Build Coastguard Worker       int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
163*795d594fSAndroid Build Coastguard Worker       EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
164*795d594fSAndroid Build Coastguard Worker     }
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker };
167*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,MemoryPeekByte)168*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
169*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
172*795d594fSAndroid Build Coastguard Worker   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
173*795d594fSAndroid Build Coastguard Worker   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
174*795d594fSAndroid Build Coastguard Worker   const uint8_t* base_ptr = base_array;
175*795d594fSAndroid Build Coastguard Worker 
176*795d594fSAndroid Build Coastguard Worker   JValue result;
177*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker   for (int32_t i = 0; i < kBaseLen; ++i) {
180*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
181*795d594fSAndroid Build Coastguard Worker 
182*795d594fSAndroid Build Coastguard Worker     UnstartedMemoryPeekByte(self, tmp.get(), &result, 0);
183*795d594fSAndroid Build Coastguard Worker 
184*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
185*795d594fSAndroid Build Coastguard Worker   }
186*795d594fSAndroid Build Coastguard Worker }
187*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,MemoryPeekShort)188*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
189*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
190*795d594fSAndroid Build Coastguard Worker 
191*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
192*795d594fSAndroid Build Coastguard Worker   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
193*795d594fSAndroid Build Coastguard Worker   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
194*795d594fSAndroid Build Coastguard Worker   const uint8_t* base_ptr = base_array;
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker   JValue result;
197*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker   int32_t adjusted_length = kBaseLen - sizeof(int16_t);
200*795d594fSAndroid Build Coastguard Worker   for (int32_t i = 0; i < adjusted_length; ++i) {
201*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker     UnstartedMemoryPeekShort(self, tmp.get(), &result, 0);
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker     using unaligned_short __attribute__((__aligned__(1))) = int16_t;
206*795d594fSAndroid Build Coastguard Worker     const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
207*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetS(), *short_ptr);
208*795d594fSAndroid Build Coastguard Worker   }
209*795d594fSAndroid Build Coastguard Worker }
210*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,MemoryPeekInt)211*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
212*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
215*795d594fSAndroid Build Coastguard Worker   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
216*795d594fSAndroid Build Coastguard Worker   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
217*795d594fSAndroid Build Coastguard Worker   const uint8_t* base_ptr = base_array;
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   JValue result;
220*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
221*795d594fSAndroid Build Coastguard Worker 
222*795d594fSAndroid Build Coastguard Worker   int32_t adjusted_length = kBaseLen - sizeof(int32_t);
223*795d594fSAndroid Build Coastguard Worker   for (int32_t i = 0; i < adjusted_length; ++i) {
224*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker     UnstartedMemoryPeekInt(self, tmp.get(), &result, 0);
227*795d594fSAndroid Build Coastguard Worker 
228*795d594fSAndroid Build Coastguard Worker     using unaligned_int __attribute__((__aligned__(1))) = int32_t;
229*795d594fSAndroid Build Coastguard Worker     const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
230*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetI(), *int_ptr);
231*795d594fSAndroid Build Coastguard Worker   }
232*795d594fSAndroid Build Coastguard Worker }
233*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,MemoryPeekLong)234*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
235*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
238*795d594fSAndroid Build Coastguard Worker   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
239*795d594fSAndroid Build Coastguard Worker   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
240*795d594fSAndroid Build Coastguard Worker   const uint8_t* base_ptr = base_array;
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   JValue result;
243*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
244*795d594fSAndroid Build Coastguard Worker 
245*795d594fSAndroid Build Coastguard Worker   int32_t adjusted_length = kBaseLen - sizeof(int64_t);
246*795d594fSAndroid Build Coastguard Worker   for (int32_t i = 0; i < adjusted_length; ++i) {
247*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
248*795d594fSAndroid Build Coastguard Worker 
249*795d594fSAndroid Build Coastguard Worker     UnstartedMemoryPeekLong(self, tmp.get(), &result, 0);
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker     using unaligned_long __attribute__((__aligned__(1))) = int64_t;
252*795d594fSAndroid Build Coastguard Worker     const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
253*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetJ(), *long_ptr);
254*795d594fSAndroid Build Coastguard Worker   }
255*795d594fSAndroid Build Coastguard Worker }
256*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,StringGetCharsNoCheck)257*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
258*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
261*795d594fSAndroid Build Coastguard Worker   StackHandleScope<2> hs(self);
262*795d594fSAndroid Build Coastguard Worker   // TODO: Actual UTF.
263*795d594fSAndroid Build Coastguard Worker   constexpr const char base_string[] = "abcdefghijklmnop";
264*795d594fSAndroid Build Coastguard Worker   Handle<mirror::String> h_test_string(hs.NewHandle(
265*795d594fSAndroid Build Coastguard Worker       mirror::String::AllocFromModifiedUtf8(self, base_string)));
266*795d594fSAndroid Build Coastguard Worker   constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
267*795d594fSAndroid Build Coastguard Worker   Handle<mirror::CharArray> h_char_array(hs.NewHandle(
268*795d594fSAndroid Build Coastguard Worker       mirror::CharArray::Alloc(self, kBaseLen)));
269*795d594fSAndroid Build Coastguard Worker   // A buffer so we can make sure we only modify the elements targetted.
270*795d594fSAndroid Build Coastguard Worker   uint16_t buf[kBaseLen];
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker   JValue result;
273*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker   for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
276*795d594fSAndroid Build Coastguard Worker     for (int32_t count = 0; count <= kBaseLen; ++count) {
277*795d594fSAndroid Build Coastguard Worker       for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
278*795d594fSAndroid Build Coastguard Worker         // Only do it when in bounds.
279*795d594fSAndroid Build Coastguard Worker         if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
280*795d594fSAndroid Build Coastguard Worker           tmp->SetVRegReference(0, h_test_string.Get());
281*795d594fSAndroid Build Coastguard Worker           tmp->SetVReg(1, start_index);
282*795d594fSAndroid Build Coastguard Worker           tmp->SetVReg(2, count);
283*795d594fSAndroid Build Coastguard Worker           tmp->SetVRegReference(3, h_char_array.Get());
284*795d594fSAndroid Build Coastguard Worker           tmp->SetVReg(3, trg_offset);
285*795d594fSAndroid Build Coastguard Worker 
286*795d594fSAndroid Build Coastguard Worker           // Copy the char_array into buf.
287*795d594fSAndroid Build Coastguard Worker           memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker           UnstartedStringCharAt(self, tmp.get(), &result, 0);
290*795d594fSAndroid Build Coastguard Worker 
291*795d594fSAndroid Build Coastguard Worker           uint16_t* data = h_char_array->GetData();
292*795d594fSAndroid Build Coastguard Worker 
293*795d594fSAndroid Build Coastguard Worker           bool success = true;
294*795d594fSAndroid Build Coastguard Worker 
295*795d594fSAndroid Build Coastguard Worker           // First segment should be unchanged.
296*795d594fSAndroid Build Coastguard Worker           for (int32_t i = 0; i < trg_offset; ++i) {
297*795d594fSAndroid Build Coastguard Worker             success = success && (data[i] == buf[i]);
298*795d594fSAndroid Build Coastguard Worker           }
299*795d594fSAndroid Build Coastguard Worker           // Second segment should be a copy.
300*795d594fSAndroid Build Coastguard Worker           for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
301*795d594fSAndroid Build Coastguard Worker             success = success && (data[i] == buf[i - trg_offset + start_index]);
302*795d594fSAndroid Build Coastguard Worker           }
303*795d594fSAndroid Build Coastguard Worker           // Third segment should be unchanged.
304*795d594fSAndroid Build Coastguard Worker           for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
305*795d594fSAndroid Build Coastguard Worker             success = success && (data[i] == buf[i]);
306*795d594fSAndroid Build Coastguard Worker           }
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker           EXPECT_TRUE(success);
309*795d594fSAndroid Build Coastguard Worker         }
310*795d594fSAndroid Build Coastguard Worker       }
311*795d594fSAndroid Build Coastguard Worker     }
312*795d594fSAndroid Build Coastguard Worker   }
313*795d594fSAndroid Build Coastguard Worker }
314*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,StringCharAt)315*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, StringCharAt) {
316*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
317*795d594fSAndroid Build Coastguard Worker 
318*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
319*795d594fSAndroid Build Coastguard Worker   // TODO: Actual UTF.
320*795d594fSAndroid Build Coastguard Worker   constexpr const char* base_string = "abcdefghijklmnop";
321*795d594fSAndroid Build Coastguard Worker   int32_t base_len = static_cast<int32_t>(strlen(base_string));
322*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
323*795d594fSAndroid Build Coastguard Worker 
324*795d594fSAndroid Build Coastguard Worker   JValue result;
325*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
326*795d594fSAndroid Build Coastguard Worker 
327*795d594fSAndroid Build Coastguard Worker   for (int32_t i = 0; i < base_len; ++i) {
328*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegReference(0, test_string);
329*795d594fSAndroid Build Coastguard Worker     tmp->SetVReg(1, i);
330*795d594fSAndroid Build Coastguard Worker 
331*795d594fSAndroid Build Coastguard Worker     UnstartedStringCharAt(self, tmp.get(), &result, 0);
332*795d594fSAndroid Build Coastguard Worker 
333*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetI(), base_string[i]);
334*795d594fSAndroid Build Coastguard Worker   }
335*795d594fSAndroid Build Coastguard Worker }
336*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,StringInit)337*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, StringInit) {
338*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
339*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
340*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
341*795d594fSAndroid Build Coastguard Worker   ArtMethod* method =
342*795d594fSAndroid Build Coastguard Worker       klass->FindConstructor("(Ljava/lang/String;)V", class_linker_->GetImagePointerSize());
343*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(method != nullptr);
344*795d594fSAndroid Build Coastguard Worker 
345*795d594fSAndroid Build Coastguard Worker   // create instruction data for invoke-direct {v0, v1} of method with fake index
346*795d594fSAndroid Build Coastguard Worker   uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
347*795d594fSAndroid Build Coastguard Worker 
348*795d594fSAndroid Build Coastguard Worker   JValue result;
349*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, method, 0);
350*795d594fSAndroid Build Coastguard Worker   const char* base_string = "hello_world";
351*795d594fSAndroid Build Coastguard Worker   StackHandleScope<2> hs(self);
352*795d594fSAndroid Build Coastguard Worker   Handle<mirror::String> string_arg =
353*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
354*795d594fSAndroid Build Coastguard Worker   Handle<mirror::String> reference_empty_string =
355*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
356*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, reference_empty_string.Get());
357*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(1, string_arg.Get());
358*795d594fSAndroid Build Coastguard Worker 
359*795d594fSAndroid Build Coastguard Worker   ArtMethod* factory = WellKnownClasses::StringInitToStringFactory(method);
360*795d594fSAndroid Build Coastguard Worker   interpreter::DoCall<false>(factory,
361*795d594fSAndroid Build Coastguard Worker                              self,
362*795d594fSAndroid Build Coastguard Worker                              *shadow_frame,
363*795d594fSAndroid Build Coastguard Worker                              Instruction::At(inst_data),
364*795d594fSAndroid Build Coastguard Worker                              inst_data[0],
365*795d594fSAndroid Build Coastguard Worker                              /* string_init= */ true,
366*795d594fSAndroid Build Coastguard Worker                              &result);
367*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
368*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
369*795d594fSAndroid Build Coastguard Worker 
370*795d594fSAndroid Build Coastguard Worker   if (string_arg->IsCompressed() && string_result->IsCompressed()) {
371*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
372*795d594fSAndroid Build Coastguard Worker                      string_arg->GetLength() * sizeof(uint8_t)), 0);
373*795d594fSAndroid Build Coastguard Worker   } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
374*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
375*795d594fSAndroid Build Coastguard Worker                      string_arg->GetLength() * sizeof(uint16_t)), 0);
376*795d594fSAndroid Build Coastguard Worker   } else {
377*795d594fSAndroid Build Coastguard Worker     bool equal = true;
378*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < string_arg->GetLength(); ++i) {
379*795d594fSAndroid Build Coastguard Worker       if (string_arg->CharAt(i) != string_result->CharAt(i)) {
380*795d594fSAndroid Build Coastguard Worker         equal = false;
381*795d594fSAndroid Build Coastguard Worker         break;
382*795d594fSAndroid Build Coastguard Worker       }
383*795d594fSAndroid Build Coastguard Worker     }
384*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(equal, true);
385*795d594fSAndroid Build Coastguard Worker   }
386*795d594fSAndroid Build Coastguard Worker }
387*795d594fSAndroid Build Coastguard Worker 
388*795d594fSAndroid Build Coastguard Worker // Tests the exceptions that should be checked before modifying the destination.
389*795d594fSAndroid Build Coastguard Worker // (Doesn't check the object vs primitive case ATM.)
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTestExceptions)390*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
391*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
392*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
393*795d594fSAndroid Build Coastguard Worker   JValue result;
394*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
395*795d594fSAndroid Build Coastguard Worker 
396*795d594fSAndroid Build Coastguard Worker   // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
397*795d594fSAndroid Build Coastguard Worker   //       allocate.
398*795d594fSAndroid Build Coastguard Worker   StackHandleScope<3> hs_misc(self);
399*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker   StackHandleScope<3> hs_data(self);
402*795d594fSAndroid Build Coastguard Worker   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
403*795d594fSAndroid Build Coastguard Worker   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
404*795d594fSAndroid Build Coastguard Worker   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
405*795d594fSAndroid Build Coastguard Worker 
406*795d594fSAndroid Build Coastguard Worker   Handle<mirror::ObjectArray<mirror::Object>> array(
407*795d594fSAndroid Build Coastguard Worker       hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
408*795d594fSAndroid Build Coastguard Worker 
409*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), -1, array.Get(), 0, 0);
410*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), -1, 0);
411*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, -1);
412*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, 4);
413*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 1, 3);
414*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), 1, array.Get(), 0, 3);
415*795d594fSAndroid Build Coastguard Worker 
416*795d594fSAndroid Build Coastguard Worker   Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
417*795d594fSAndroid Build Coastguard Worker       hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
418*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, class_as_array.Get(), 0, array.Get(), 0, 0);
419*795d594fSAndroid Build Coastguard Worker   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, class_as_array.Get(), 0, 0);
420*795d594fSAndroid Build Coastguard Worker }
421*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTest)422*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
423*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
424*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
425*795d594fSAndroid Build Coastguard Worker   JValue result;
426*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
427*795d594fSAndroid Build Coastguard Worker 
428*795d594fSAndroid Build Coastguard Worker   // Simple test:
429*795d594fSAndroid Build Coastguard Worker   // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
430*795d594fSAndroid Build Coastguard Worker   {
431*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_src(self);
432*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
433*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
434*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
435*795d594fSAndroid Build Coastguard Worker 
436*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_dst(self);
437*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
438*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
439*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
440*795d594fSAndroid Build Coastguard Worker 
441*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_expected(self);
442*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_dst.GetReference(0));
443*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_dst.GetReference(1));
444*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_src.GetReference(1));
445*795d594fSAndroid Build Coastguard Worker 
446*795d594fSAndroid Build Coastguard Worker     RunArrayCopy(self,
447*795d594fSAndroid Build Coastguard Worker                  tmp.get(),
448*795d594fSAndroid Build Coastguard Worker                  false,
449*795d594fSAndroid Build Coastguard Worker                  GetClassRoot<mirror::Object>(),
450*795d594fSAndroid Build Coastguard Worker                  GetClassRoot<mirror::Object>(),
451*795d594fSAndroid Build Coastguard Worker                  hs_src,
452*795d594fSAndroid Build Coastguard Worker                  1,
453*795d594fSAndroid Build Coastguard Worker                  hs_dst,
454*795d594fSAndroid Build Coastguard Worker                  2,
455*795d594fSAndroid Build Coastguard Worker                  1,
456*795d594fSAndroid Build Coastguard Worker                  hs_expected);
457*795d594fSAndroid Build Coastguard Worker   }
458*795d594fSAndroid Build Coastguard Worker 
459*795d594fSAndroid Build Coastguard Worker   // Simple test:
460*795d594fSAndroid Build Coastguard Worker   // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
461*795d594fSAndroid Build Coastguard Worker   {
462*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_src(self);
463*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
464*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
465*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
466*795d594fSAndroid Build Coastguard Worker 
467*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_dst(self);
468*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
469*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
470*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
471*795d594fSAndroid Build Coastguard Worker 
472*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_expected(self);
473*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_dst.GetReference(0));
474*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_src.GetReference(1));
475*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_dst.GetReference(2));
476*795d594fSAndroid Build Coastguard Worker 
477*795d594fSAndroid Build Coastguard Worker     RunArrayCopy(self,
478*795d594fSAndroid Build Coastguard Worker                  tmp.get(),
479*795d594fSAndroid Build Coastguard Worker                  false,
480*795d594fSAndroid Build Coastguard Worker                  GetClassRoot<mirror::Object>(),
481*795d594fSAndroid Build Coastguard Worker                  GetClassRoot<mirror::String>(),
482*795d594fSAndroid Build Coastguard Worker                  hs_src,
483*795d594fSAndroid Build Coastguard Worker                  1,
484*795d594fSAndroid Build Coastguard Worker                  hs_dst,
485*795d594fSAndroid Build Coastguard Worker                  1,
486*795d594fSAndroid Build Coastguard Worker                  1,
487*795d594fSAndroid Build Coastguard Worker                  hs_expected);
488*795d594fSAndroid Build Coastguard Worker   }
489*795d594fSAndroid Build Coastguard Worker 
490*795d594fSAndroid Build Coastguard Worker   // Simple test:
491*795d594fSAndroid Build Coastguard Worker   // [1,*,3] into [4,5,6] = [1,5,6] + exc
492*795d594fSAndroid Build Coastguard Worker   {
493*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_src(self);
494*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
495*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(GetClassRoot<mirror::String>());
496*795d594fSAndroid Build Coastguard Worker     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
497*795d594fSAndroid Build Coastguard Worker 
498*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_dst(self);
499*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
500*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
501*795d594fSAndroid Build Coastguard Worker     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
502*795d594fSAndroid Build Coastguard Worker 
503*795d594fSAndroid Build Coastguard Worker     StackHandleScope<3> hs_expected(self);
504*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_src.GetReference(0));
505*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_dst.GetReference(1));
506*795d594fSAndroid Build Coastguard Worker     hs_expected.NewHandle(hs_dst.GetReference(2));
507*795d594fSAndroid Build Coastguard Worker 
508*795d594fSAndroid Build Coastguard Worker     RunArrayCopy(self,
509*795d594fSAndroid Build Coastguard Worker                  tmp.get(),
510*795d594fSAndroid Build Coastguard Worker                  true,
511*795d594fSAndroid Build Coastguard Worker                  GetClassRoot<mirror::Object>(),
512*795d594fSAndroid Build Coastguard Worker                  GetClassRoot<mirror::String>(),
513*795d594fSAndroid Build Coastguard Worker                  hs_src,
514*795d594fSAndroid Build Coastguard Worker                  0,
515*795d594fSAndroid Build Coastguard Worker                  hs_dst,
516*795d594fSAndroid Build Coastguard Worker                  0,
517*795d594fSAndroid Build Coastguard Worker                  3,
518*795d594fSAndroid Build Coastguard Worker                  hs_expected);
519*795d594fSAndroid Build Coastguard Worker   }
520*795d594fSAndroid Build Coastguard Worker }
521*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,IntegerParseIntTest)522*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
523*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
524*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
525*795d594fSAndroid Build Coastguard Worker 
526*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
527*795d594fSAndroid Build Coastguard Worker 
528*795d594fSAndroid Build Coastguard Worker   // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
529*795d594fSAndroid Build Coastguard Worker   // suffixes).
530*795d594fSAndroid Build Coastguard Worker   constexpr const char* test_string = "-2147483646";
531*795d594fSAndroid Build Coastguard Worker   constexpr int32_t test_values[] = {
532*795d594fSAndroid Build Coastguard Worker                 6,
533*795d594fSAndroid Build Coastguard Worker                46,
534*795d594fSAndroid Build Coastguard Worker               646,
535*795d594fSAndroid Build Coastguard Worker              3646,
536*795d594fSAndroid Build Coastguard Worker             83646,
537*795d594fSAndroid Build Coastguard Worker            483646,
538*795d594fSAndroid Build Coastguard Worker           7483646,
539*795d594fSAndroid Build Coastguard Worker          47483646,
540*795d594fSAndroid Build Coastguard Worker         147483646,
541*795d594fSAndroid Build Coastguard Worker        2147483646,
542*795d594fSAndroid Build Coastguard Worker       -2147483646
543*795d594fSAndroid Build Coastguard Worker   };
544*795d594fSAndroid Build Coastguard Worker 
545*795d594fSAndroid Build Coastguard Worker   static_assert(arraysize(test_values) == 11U, "test_values");
546*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(strlen(test_string), 11U);
547*795d594fSAndroid Build Coastguard Worker 
548*795d594fSAndroid Build Coastguard Worker   for (size_t i = 0; i <= 10; ++i) {
549*795d594fSAndroid Build Coastguard Worker     const char* test_value = &test_string[10 - i];
550*795d594fSAndroid Build Coastguard Worker 
551*795d594fSAndroid Build Coastguard Worker     StackHandleScope<1> hs_str(self);
552*795d594fSAndroid Build Coastguard Worker     Handle<mirror::String> h_str(
553*795d594fSAndroid Build Coastguard Worker         hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
554*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(h_str.Get(), nullptr);
555*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(self->IsExceptionPending());
556*795d594fSAndroid Build Coastguard Worker 
557*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegReference(0, h_str.Get());
558*795d594fSAndroid Build Coastguard Worker 
559*795d594fSAndroid Build Coastguard Worker     JValue result;
560*795d594fSAndroid Build Coastguard Worker     UnstartedIntegerParseInt(self, tmp.get(), &result, 0);
561*795d594fSAndroid Build Coastguard Worker 
562*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(self->IsExceptionPending());
563*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetI(), test_values[i]);
564*795d594fSAndroid Build Coastguard Worker   }
565*795d594fSAndroid Build Coastguard Worker }
566*795d594fSAndroid Build Coastguard Worker 
567*795d594fSAndroid Build Coastguard Worker // Right now the same as Integer.Parse
TEST_F(UnstartedRuntimeTest,LongParseLongTest)568*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
569*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
570*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
573*795d594fSAndroid Build Coastguard Worker 
574*795d594fSAndroid Build Coastguard Worker   // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
575*795d594fSAndroid Build Coastguard Worker   // suffixes).
576*795d594fSAndroid Build Coastguard Worker   constexpr const char* test_string = "-2147483646";
577*795d594fSAndroid Build Coastguard Worker   constexpr int64_t test_values[] = {
578*795d594fSAndroid Build Coastguard Worker                 6,
579*795d594fSAndroid Build Coastguard Worker                46,
580*795d594fSAndroid Build Coastguard Worker               646,
581*795d594fSAndroid Build Coastguard Worker              3646,
582*795d594fSAndroid Build Coastguard Worker             83646,
583*795d594fSAndroid Build Coastguard Worker            483646,
584*795d594fSAndroid Build Coastguard Worker           7483646,
585*795d594fSAndroid Build Coastguard Worker          47483646,
586*795d594fSAndroid Build Coastguard Worker         147483646,
587*795d594fSAndroid Build Coastguard Worker        2147483646,
588*795d594fSAndroid Build Coastguard Worker       -2147483646
589*795d594fSAndroid Build Coastguard Worker   };
590*795d594fSAndroid Build Coastguard Worker 
591*795d594fSAndroid Build Coastguard Worker   static_assert(arraysize(test_values) == 11U, "test_values");
592*795d594fSAndroid Build Coastguard Worker   CHECK_EQ(strlen(test_string), 11U);
593*795d594fSAndroid Build Coastguard Worker 
594*795d594fSAndroid Build Coastguard Worker   for (size_t i = 0; i <= 10; ++i) {
595*795d594fSAndroid Build Coastguard Worker     const char* test_value = &test_string[10 - i];
596*795d594fSAndroid Build Coastguard Worker 
597*795d594fSAndroid Build Coastguard Worker     StackHandleScope<1> hs_str(self);
598*795d594fSAndroid Build Coastguard Worker     Handle<mirror::String> h_str(
599*795d594fSAndroid Build Coastguard Worker         hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
600*795d594fSAndroid Build Coastguard Worker     ASSERT_NE(h_str.Get(), nullptr);
601*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(self->IsExceptionPending());
602*795d594fSAndroid Build Coastguard Worker 
603*795d594fSAndroid Build Coastguard Worker     tmp->SetVRegReference(0, h_str.Get());
604*795d594fSAndroid Build Coastguard Worker 
605*795d594fSAndroid Build Coastguard Worker     JValue result;
606*795d594fSAndroid Build Coastguard Worker     UnstartedLongParseLong(self, tmp.get(), &result, 0);
607*795d594fSAndroid Build Coastguard Worker 
608*795d594fSAndroid Build Coastguard Worker     ASSERT_FALSE(self->IsExceptionPending());
609*795d594fSAndroid Build Coastguard Worker     EXPECT_EQ(result.GetJ(), test_values[i]);
610*795d594fSAndroid Build Coastguard Worker   }
611*795d594fSAndroid Build Coastguard Worker }
612*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,Ceil)613*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, Ceil) {
614*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
615*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
616*795d594fSAndroid Build Coastguard Worker 
617*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
618*795d594fSAndroid Build Coastguard Worker 
619*795d594fSAndroid Build Coastguard Worker   constexpr double nan = std::numeric_limits<double>::quiet_NaN();
620*795d594fSAndroid Build Coastguard Worker   constexpr double inf = std::numeric_limits<double>::infinity();
621*795d594fSAndroid Build Coastguard Worker   constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
622*795d594fSAndroid Build Coastguard Worker   constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
623*795d594fSAndroid Build Coastguard Worker   constexpr double test_pairs[][2] = {
624*795d594fSAndroid Build Coastguard Worker       { -0.0, -0.0 },
625*795d594fSAndroid Build Coastguard Worker       {  0.0,  0.0 },
626*795d594fSAndroid Build Coastguard Worker       { -0.5, -0.0 },
627*795d594fSAndroid Build Coastguard Worker       { -1.0, -1.0 },
628*795d594fSAndroid Build Coastguard Worker       {  0.5,  1.0 },
629*795d594fSAndroid Build Coastguard Worker       {  1.0,  1.0 },
630*795d594fSAndroid Build Coastguard Worker       {  nan,  nan },
631*795d594fSAndroid Build Coastguard Worker       {  inf,  inf },
632*795d594fSAndroid Build Coastguard Worker       { -inf, -inf },
633*795d594fSAndroid Build Coastguard Worker       {  ld1,  ld1 },
634*795d594fSAndroid Build Coastguard Worker       {  ld2,  ld2 }
635*795d594fSAndroid Build Coastguard Worker   };
636*795d594fSAndroid Build Coastguard Worker 
637*795d594fSAndroid Build Coastguard Worker   TestCeilFloor(/* ceil= */ true, self, tmp.get(), test_pairs, arraysize(test_pairs));
638*795d594fSAndroid Build Coastguard Worker }
639*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,Floor)640*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, Floor) {
641*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
642*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
643*795d594fSAndroid Build Coastguard Worker 
644*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
645*795d594fSAndroid Build Coastguard Worker 
646*795d594fSAndroid Build Coastguard Worker   constexpr double nan = std::numeric_limits<double>::quiet_NaN();
647*795d594fSAndroid Build Coastguard Worker   constexpr double inf = std::numeric_limits<double>::infinity();
648*795d594fSAndroid Build Coastguard Worker   constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
649*795d594fSAndroid Build Coastguard Worker   constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
650*795d594fSAndroid Build Coastguard Worker   constexpr double test_pairs[][2] = {
651*795d594fSAndroid Build Coastguard Worker       { -0.0, -0.0 },
652*795d594fSAndroid Build Coastguard Worker       {  0.0,  0.0 },
653*795d594fSAndroid Build Coastguard Worker       { -0.5, -1.0 },
654*795d594fSAndroid Build Coastguard Worker       { -1.0, -1.0 },
655*795d594fSAndroid Build Coastguard Worker       {  0.5,  0.0 },
656*795d594fSAndroid Build Coastguard Worker       {  1.0,  1.0 },
657*795d594fSAndroid Build Coastguard Worker       {  nan,  nan },
658*795d594fSAndroid Build Coastguard Worker       {  inf,  inf },
659*795d594fSAndroid Build Coastguard Worker       { -inf, -inf },
660*795d594fSAndroid Build Coastguard Worker       {  ld1,  ld1 },
661*795d594fSAndroid Build Coastguard Worker       {  ld2,  ld2 }
662*795d594fSAndroid Build Coastguard Worker   };
663*795d594fSAndroid Build Coastguard Worker 
664*795d594fSAndroid Build Coastguard Worker   TestCeilFloor(/* ceil= */ false, self, tmp.get(), test_pairs, arraysize(test_pairs));
665*795d594fSAndroid Build Coastguard Worker }
666*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,ToLowerUpper)667*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
668*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
669*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
670*795d594fSAndroid Build Coastguard Worker 
671*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
672*795d594fSAndroid Build Coastguard Worker 
673*795d594fSAndroid Build Coastguard Worker   std::locale c_locale("C");
674*795d594fSAndroid Build Coastguard Worker 
675*795d594fSAndroid Build Coastguard Worker   // Check ASCII.
676*795d594fSAndroid Build Coastguard Worker   for (uint32_t i = 0; i < 128; ++i) {
677*795d594fSAndroid Build Coastguard Worker     bool c_upper = std::isupper(static_cast<char>(i), c_locale);
678*795d594fSAndroid Build Coastguard Worker     bool c_lower = std::islower(static_cast<char>(i), c_locale);
679*795d594fSAndroid Build Coastguard Worker     EXPECT_FALSE(c_upper && c_lower) << i;
680*795d594fSAndroid Build Coastguard Worker 
681*795d594fSAndroid Build Coastguard Worker     // Check toLowerCase.
682*795d594fSAndroid Build Coastguard Worker     {
683*795d594fSAndroid Build Coastguard Worker       JValue result;
684*795d594fSAndroid Build Coastguard Worker       tmp->SetVReg(0, static_cast<int32_t>(i));
685*795d594fSAndroid Build Coastguard Worker       UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
686*795d594fSAndroid Build Coastguard Worker       ASSERT_FALSE(self->IsExceptionPending());
687*795d594fSAndroid Build Coastguard Worker       uint32_t lower_result = static_cast<uint32_t>(result.GetI());
688*795d594fSAndroid Build Coastguard Worker       if (c_lower) {
689*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(i, lower_result);
690*795d594fSAndroid Build Coastguard Worker       } else if (c_upper) {
691*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
692*795d594fSAndroid Build Coastguard Worker                   lower_result);
693*795d594fSAndroid Build Coastguard Worker       } else {
694*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(i, lower_result);
695*795d594fSAndroid Build Coastguard Worker       }
696*795d594fSAndroid Build Coastguard Worker     }
697*795d594fSAndroid Build Coastguard Worker 
698*795d594fSAndroid Build Coastguard Worker     // Check toUpperCase.
699*795d594fSAndroid Build Coastguard Worker     {
700*795d594fSAndroid Build Coastguard Worker       JValue result2;
701*795d594fSAndroid Build Coastguard Worker       tmp->SetVReg(0, static_cast<int32_t>(i));
702*795d594fSAndroid Build Coastguard Worker       UnstartedCharacterToUpperCase(self, tmp.get(), &result2, 0);
703*795d594fSAndroid Build Coastguard Worker       ASSERT_FALSE(self->IsExceptionPending());
704*795d594fSAndroid Build Coastguard Worker       uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
705*795d594fSAndroid Build Coastguard Worker       if (c_upper) {
706*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(i, upper_result);
707*795d594fSAndroid Build Coastguard Worker       } else if (c_lower) {
708*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
709*795d594fSAndroid Build Coastguard Worker                   upper_result);
710*795d594fSAndroid Build Coastguard Worker       } else {
711*795d594fSAndroid Build Coastguard Worker         EXPECT_EQ(i, upper_result);
712*795d594fSAndroid Build Coastguard Worker       }
713*795d594fSAndroid Build Coastguard Worker     }
714*795d594fSAndroid Build Coastguard Worker   }
715*795d594fSAndroid Build Coastguard Worker }
716*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,Sin)717*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, Sin) {
718*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
719*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
720*795d594fSAndroid Build Coastguard Worker 
721*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
722*795d594fSAndroid Build Coastguard Worker 
723*795d594fSAndroid Build Coastguard Worker   // Test an important value, PI/6. That's the one we see in practice.
724*795d594fSAndroid Build Coastguard Worker   constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
725*795d594fSAndroid Build Coastguard Worker   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
726*795d594fSAndroid Build Coastguard Worker 
727*795d594fSAndroid Build Coastguard Worker   JValue result;
728*795d594fSAndroid Build Coastguard Worker   UnstartedMathSin(self, tmp.get(), &result, 0);
729*795d594fSAndroid Build Coastguard Worker 
730*795d594fSAndroid Build Coastguard Worker   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
731*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
732*795d594fSAndroid Build Coastguard Worker }
733*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,Cos)734*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, Cos) {
735*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
736*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
737*795d594fSAndroid Build Coastguard Worker 
738*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
739*795d594fSAndroid Build Coastguard Worker 
740*795d594fSAndroid Build Coastguard Worker   // Test an important value, PI/6. That's the one we see in practice.
741*795d594fSAndroid Build Coastguard Worker   constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
742*795d594fSAndroid Build Coastguard Worker   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
743*795d594fSAndroid Build Coastguard Worker 
744*795d594fSAndroid Build Coastguard Worker   JValue result;
745*795d594fSAndroid Build Coastguard Worker   UnstartedMathCos(self, tmp.get(), &result, 0);
746*795d594fSAndroid Build Coastguard Worker 
747*795d594fSAndroid Build Coastguard Worker   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
748*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
749*795d594fSAndroid Build Coastguard Worker }
750*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,Pow)751*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, Pow) {
752*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
753*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
754*795d594fSAndroid Build Coastguard Worker 
755*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
756*795d594fSAndroid Build Coastguard Worker 
757*795d594fSAndroid Build Coastguard Worker   // Test an important pair.
758*795d594fSAndroid Build Coastguard Worker   constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
759*795d594fSAndroid Build Coastguard Worker   constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
760*795d594fSAndroid Build Coastguard Worker 
761*795d594fSAndroid Build Coastguard Worker   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
762*795d594fSAndroid Build Coastguard Worker   tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
763*795d594fSAndroid Build Coastguard Worker 
764*795d594fSAndroid Build Coastguard Worker   JValue result;
765*795d594fSAndroid Build Coastguard Worker   UnstartedMathPow(self, tmp.get(), &result, 0);
766*795d594fSAndroid Build Coastguard Worker 
767*795d594fSAndroid Build Coastguard Worker   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
768*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
769*795d594fSAndroid Build Coastguard Worker }
770*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,IsAnonymousClass)771*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
772*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
773*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
774*795d594fSAndroid Build Coastguard Worker 
775*795d594fSAndroid Build Coastguard Worker   JValue result;
776*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, 0);
777*795d594fSAndroid Build Coastguard Worker 
778*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
779*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, class_klass);
780*795d594fSAndroid Build Coastguard Worker   UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
781*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.GetZ(), 0);
782*795d594fSAndroid Build Coastguard Worker 
783*795d594fSAndroid Build Coastguard Worker   jobject class_loader = LoadDex("Nested");
784*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(soa.Self());
785*795d594fSAndroid Build Coastguard Worker   Handle<mirror::ClassLoader> loader(
786*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
787*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> c = FindClass("LNested$1;", loader);
788*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(c != nullptr);
789*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, c);
790*795d594fSAndroid Build Coastguard Worker   UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
791*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.GetZ(), 1);
792*795d594fSAndroid Build Coastguard Worker }
793*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,GetDeclaringClass)794*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
795*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
796*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
797*795d594fSAndroid Build Coastguard Worker 
798*795d594fSAndroid Build Coastguard Worker   JValue result;
799*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, 0);
800*795d594fSAndroid Build Coastguard Worker 
801*795d594fSAndroid Build Coastguard Worker   jobject class_loader = LoadDex("Nested");
802*795d594fSAndroid Build Coastguard Worker   StackHandleScope<4> hs(self);
803*795d594fSAndroid Build Coastguard Worker   Handle<mirror::ClassLoader> loader(
804*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
805*795d594fSAndroid Build Coastguard Worker 
806*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> nested_klass = hs.NewHandle(FindClass("LNested;", loader));
807*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> inner_klass = hs.NewHandle(FindClass("LNested$Inner;", loader));
808*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> anon_klass = hs.NewHandle(FindClass("LNested$1;", loader));
809*795d594fSAndroid Build Coastguard Worker 
810*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, nested_klass.Get());
811*795d594fSAndroid Build Coastguard Worker   UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
812*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.GetL(), nullptr);
813*795d594fSAndroid Build Coastguard Worker 
814*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, inner_klass.Get());
815*795d594fSAndroid Build Coastguard Worker   UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
816*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.GetL(), nested_klass.Get());
817*795d594fSAndroid Build Coastguard Worker 
818*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, anon_klass.Get());
819*795d594fSAndroid Build Coastguard Worker   UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
820*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(result.GetL(), nullptr);
821*795d594fSAndroid Build Coastguard Worker }
822*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,ThreadLocalGet)823*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
824*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
825*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
826*795d594fSAndroid Build Coastguard Worker 
827*795d594fSAndroid Build Coastguard Worker   JValue result;
828*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, 0);
829*795d594fSAndroid Build Coastguard Worker 
830*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
831*795d594fSAndroid Build Coastguard Worker 
832*795d594fSAndroid Build Coastguard Worker   // Positive test. See that We get something for float conversion.
833*795d594fSAndroid Build Coastguard Worker   {
834*795d594fSAndroid Build Coastguard Worker     Handle<mirror::Class> floating_decimal = hs.NewHandle(
835*795d594fSAndroid Build Coastguard Worker         FindClass("Ljdk/internal/math/FloatingDecimal;", ScopedNullHandle<mirror::ClassLoader>()));
836*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(floating_decimal != nullptr);
837*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(class_linker_->EnsureInitialized(self, floating_decimal, true, true));
838*795d594fSAndroid Build Coastguard Worker 
839*795d594fSAndroid Build Coastguard Worker     ArtMethod* caller_method = floating_decimal->FindClassMethod(
840*795d594fSAndroid Build Coastguard Worker         "getBinaryToASCIIBuffer",
841*795d594fSAndroid Build Coastguard Worker         "()Ljdk/internal/math/FloatingDecimal$BinaryToASCIIBuffer;",
842*795d594fSAndroid Build Coastguard Worker         class_linker_->GetImagePointerSize());
843*795d594fSAndroid Build Coastguard Worker     // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
844*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(caller_method != nullptr);
845*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(caller_method->IsDirect());
846*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
847*795d594fSAndroid Build Coastguard Worker     UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, caller_method, 0);
848*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetLink(caller_frame.get());
849*795d594fSAndroid Build Coastguard Worker 
850*795d594fSAndroid Build Coastguard Worker     UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
851*795d594fSAndroid Build Coastguard Worker     EXPECT_TRUE(result.GetL() != nullptr);
852*795d594fSAndroid Build Coastguard Worker     EXPECT_FALSE(self->IsExceptionPending());
853*795d594fSAndroid Build Coastguard Worker 
854*795d594fSAndroid Build Coastguard Worker     shadow_frame->ClearLink();
855*795d594fSAndroid Build Coastguard Worker   }
856*795d594fSAndroid Build Coastguard Worker }
857*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,FloatConversion)858*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, FloatConversion) {
859*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
860*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
861*795d594fSAndroid Build Coastguard Worker 
862*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
863*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> double_class =
864*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(FindClass("Ljava/lang/Double;", ScopedNullHandle<mirror::ClassLoader>()));
865*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(double_class != nullptr);
866*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(class_linker_->EnsureInitialized(self, double_class, true, true));
867*795d594fSAndroid Build Coastguard Worker 
868*795d594fSAndroid Build Coastguard Worker   ArtMethod* method = double_class->FindClassMethod("toString",
869*795d594fSAndroid Build Coastguard Worker                                                     "(D)Ljava/lang/String;",
870*795d594fSAndroid Build Coastguard Worker                                                     class_linker_->GetImagePointerSize());
871*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(method != nullptr);
872*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(method->IsDirect());
873*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
874*795d594fSAndroid Build Coastguard Worker 
875*795d594fSAndroid Build Coastguard Worker   // create instruction data for invoke-direct {v0, v1} of method with fake index
876*795d594fSAndroid Build Coastguard Worker   uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
877*795d594fSAndroid Build Coastguard Worker 
878*795d594fSAndroid Build Coastguard Worker   JValue result;
879*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, method, 0);
880*795d594fSAndroid Build Coastguard Worker 
881*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegDouble(0, 1.23);
882*795d594fSAndroid Build Coastguard Worker   interpreter::DoCall<false>(method,
883*795d594fSAndroid Build Coastguard Worker                              self,
884*795d594fSAndroid Build Coastguard Worker                              *shadow_frame,
885*795d594fSAndroid Build Coastguard Worker                              Instruction::At(inst_data),
886*795d594fSAndroid Build Coastguard Worker                              inst_data[0],
887*795d594fSAndroid Build Coastguard Worker                              /* string_init= */ false,
888*795d594fSAndroid Build Coastguard Worker                              &result);
889*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
890*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(string_result != nullptr);
891*795d594fSAndroid Build Coastguard Worker 
892*795d594fSAndroid Build Coastguard Worker   std::string mod_utf = string_result->ToModifiedUtf8();
893*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ("1.23", mod_utf);
894*795d594fSAndroid Build Coastguard Worker }
895*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,LogManager)896*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, LogManager) {
897*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
898*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
899*795d594fSAndroid Build Coastguard Worker 
900*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
901*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> log_manager_class = hs.NewHandle(
902*795d594fSAndroid Build Coastguard Worker       FindClass("Ljava/util/logging/LogManager;", ScopedNullHandle<mirror::ClassLoader>()));
903*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(log_manager_class.Get() != nullptr);
904*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(class_linker_->EnsureInitialized(self, log_manager_class, true, true));
905*795d594fSAndroid Build Coastguard Worker }
906*795d594fSAndroid Build Coastguard Worker 
907*795d594fSAndroid Build Coastguard Worker class UnstartedClassForNameTest : public UnstartedRuntimeTest {
908*795d594fSAndroid Build Coastguard Worker  public:
909*795d594fSAndroid Build Coastguard Worker   template <typename T>
RunTest(T && runner)910*795d594fSAndroid Build Coastguard Worker   void RunTest(T&& runner) {
911*795d594fSAndroid Build Coastguard Worker     Thread* self = Thread::Current();
912*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(self);
913*795d594fSAndroid Build Coastguard Worker 
914*795d594fSAndroid Build Coastguard Worker     // Ensure that Class is initialized.
915*795d594fSAndroid Build Coastguard Worker     CHECK(GetClassRoot<mirror::Class>()->IsInitialized());
916*795d594fSAndroid Build Coastguard Worker 
917*795d594fSAndroid Build Coastguard Worker     // A selection of classes from different core classpath components.
918*795d594fSAndroid Build Coastguard Worker     constexpr const char* kTestCases[] = {
919*795d594fSAndroid Build Coastguard Worker         "java.net.CookieManager",  // From libcore.
920*795d594fSAndroid Build Coastguard Worker         "dalvik.system.ClassExt",  // From libart.
921*795d594fSAndroid Build Coastguard Worker     };
922*795d594fSAndroid Build Coastguard Worker 
923*795d594fSAndroid Build Coastguard Worker     JValue result;
924*795d594fSAndroid Build Coastguard Worker     UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, 0);
925*795d594fSAndroid Build Coastguard Worker 
926*795d594fSAndroid Build Coastguard Worker     for (const char* name : kTestCases) {
927*795d594fSAndroid Build Coastguard Worker       ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
928*795d594fSAndroid Build Coastguard Worker       CHECK(name_string != nullptr);
929*795d594fSAndroid Build Coastguard Worker       CHECK(!self->IsExceptionPending());
930*795d594fSAndroid Build Coastguard Worker 
931*795d594fSAndroid Build Coastguard Worker       runner(self, shadow_frame.get(), name_string, &result);
932*795d594fSAndroid Build Coastguard Worker 
933*795d594fSAndroid Build Coastguard Worker       CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
934*795d594fSAndroid Build Coastguard Worker       CHECK(result.GetL() != nullptr) << name;
935*795d594fSAndroid Build Coastguard Worker     }
936*795d594fSAndroid Build Coastguard Worker   }
937*795d594fSAndroid Build Coastguard Worker };
938*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedClassForNameTest,ClassForName)939*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedClassForNameTest, ClassForName) {
940*795d594fSAndroid Build Coastguard Worker   auto runner = [](Thread* self,
941*795d594fSAndroid Build Coastguard Worker                    ShadowFrame* shadow_frame,
942*795d594fSAndroid Build Coastguard Worker                    ObjPtr<mirror::String> name,
943*795d594fSAndroid Build Coastguard Worker                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
944*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVRegReference(0, name);
945*795d594fSAndroid Build Coastguard Worker     UnstartedClassForName(self, shadow_frame, result, 0);
946*795d594fSAndroid Build Coastguard Worker   };
947*795d594fSAndroid Build Coastguard Worker   RunTest(runner);
948*795d594fSAndroid Build Coastguard Worker }
949*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedClassForNameTest,ClassForNameLong)950*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
951*795d594fSAndroid Build Coastguard Worker   auto runner = [](Thread* self,
952*795d594fSAndroid Build Coastguard Worker                    ShadowFrame* shadow_frame,
953*795d594fSAndroid Build Coastguard Worker                    ObjPtr<mirror::String> name,
954*795d594fSAndroid Build Coastguard Worker                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
955*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVRegReference(0, name);
956*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVReg(1, 0);
957*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVRegReference(2, nullptr);
958*795d594fSAndroid Build Coastguard Worker     UnstartedClassForNameLong(self, shadow_frame, result, 0);
959*795d594fSAndroid Build Coastguard Worker   };
960*795d594fSAndroid Build Coastguard Worker   RunTest(runner);
961*795d594fSAndroid Build Coastguard Worker }
962*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoader)963*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
964*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
965*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
966*795d594fSAndroid Build Coastguard Worker 
967*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
968*795d594fSAndroid Build Coastguard Worker   Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
969*795d594fSAndroid Build Coastguard Worker 
970*795d594fSAndroid Build Coastguard Worker   auto runner = [&](Thread* th,
971*795d594fSAndroid Build Coastguard Worker                     ShadowFrame* shadow_frame,
972*795d594fSAndroid Build Coastguard Worker                     ObjPtr<mirror::String> name,
973*795d594fSAndroid Build Coastguard Worker                     JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
974*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVRegReference(0, name);
975*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVReg(1, 0);
976*795d594fSAndroid Build Coastguard Worker     shadow_frame->SetVRegReference(2, boot_cp.Get());
977*795d594fSAndroid Build Coastguard Worker     UnstartedClassForNameLong(th, shadow_frame, result, 0);
978*795d594fSAndroid Build Coastguard Worker   };
979*795d594fSAndroid Build Coastguard Worker   RunTest(runner);
980*795d594fSAndroid Build Coastguard Worker }
981*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,ClassGetSignatureAnnotation)982*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
983*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
984*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
985*795d594fSAndroid Build Coastguard Worker 
986*795d594fSAndroid Build Coastguard Worker   StackHandleScope<1> hs(self);
987*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> list_class =
988*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(FindClass("Ljava/util/List;", ScopedNullHandle<mirror::ClassLoader>()));
989*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(list_class.Get() != nullptr);
990*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(class_linker_->EnsureInitialized(self, list_class, true, true));
991*795d594fSAndroid Build Coastguard Worker 
992*795d594fSAndroid Build Coastguard Worker   JValue result;
993*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, 0);
994*795d594fSAndroid Build Coastguard Worker 
995*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, list_class.Get());
996*795d594fSAndroid Build Coastguard Worker   UnstartedClassGetSignatureAnnotation(self, shadow_frame.get(), &result, 0);
997*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(result.GetL() != nullptr);
998*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(self->IsExceptionPending());
999*795d594fSAndroid Build Coastguard Worker 
1000*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(result.GetL()->IsObjectArray());
1001*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1002*795d594fSAndroid Build Coastguard Worker       result.GetL()->AsObjectArray<mirror::Object>();
1003*795d594fSAndroid Build Coastguard Worker   std::ostringstream oss;
1004*795d594fSAndroid Build Coastguard Worker   for (int32_t i = 0; i != array->GetLength(); ++i) {
1005*795d594fSAndroid Build Coastguard Worker     ObjPtr<mirror::Object> elem = array->Get(i);
1006*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(elem != nullptr);
1007*795d594fSAndroid Build Coastguard Worker     ASSERT_TRUE(elem->IsString());
1008*795d594fSAndroid Build Coastguard Worker     oss << elem->AsString()->ToModifiedUtf8();
1009*795d594fSAndroid Build Coastguard Worker   }
1010*795d594fSAndroid Build Coastguard Worker   std::string output_string = oss.str();
1011*795d594fSAndroid Build Coastguard Worker   ASSERT_EQ(output_string,
1012*795d594fSAndroid Build Coastguard Worker             "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/SequencedCollection<TE;>;"
1013*795d594fSAndroid Build Coastguard Worker             "Ljava/util/Collection<TE;>;");
1014*795d594fSAndroid Build Coastguard Worker }
1015*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,ConstructorNewInstance0)1016*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1017*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1018*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
1019*795d594fSAndroid Build Coastguard Worker 
1020*795d594fSAndroid Build Coastguard Worker   StackHandleScope<4> hs(self);
1021*795d594fSAndroid Build Coastguard Worker 
1022*795d594fSAndroid Build Coastguard Worker   // Get Throwable.
1023*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
1024*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(class_linker_->EnsureInitialized(self, throw_class, true, true));
1025*795d594fSAndroid Build Coastguard Worker 
1026*795d594fSAndroid Build Coastguard Worker   // Get an input object.
1027*795d594fSAndroid Build Coastguard Worker   Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1028*795d594fSAndroid Build Coastguard Worker 
1029*795d594fSAndroid Build Coastguard Worker   // Find the constructor.
1030*795d594fSAndroid Build Coastguard Worker   PointerSize pointer_size = class_linker_->GetImagePointerSize();
1031*795d594fSAndroid Build Coastguard Worker   ArtMethod* throw_cons = throw_class->FindConstructor("(Ljava/lang/String;)V", pointer_size);
1032*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(throw_cons != nullptr);
1033*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Constructor> cons = hs.NewHandle((pointer_size == PointerSize::k64)
1034*795d594fSAndroid Build Coastguard Worker       ? mirror::Constructor::CreateFromArtMethod<PointerSize::k64>(self, throw_cons)
1035*795d594fSAndroid Build Coastguard Worker       : mirror::Constructor::CreateFromArtMethod<PointerSize::k32>(self, throw_cons));
1036*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(cons != nullptr);
1037*795d594fSAndroid Build Coastguard Worker 
1038*795d594fSAndroid Build Coastguard Worker   Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
1039*795d594fSAndroid Build Coastguard Worker       mirror::ObjectArray<mirror::Object>::Alloc(
1040*795d594fSAndroid Build Coastguard Worker           self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
1041*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(args != nullptr);
1042*795d594fSAndroid Build Coastguard Worker   args->Set(0, input.Get());
1043*795d594fSAndroid Build Coastguard Worker 
1044*795d594fSAndroid Build Coastguard Worker   // OK, we're ready now.
1045*795d594fSAndroid Build Coastguard Worker   JValue result;
1046*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, 0);
1047*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(0, cons.Get());
1048*795d594fSAndroid Build Coastguard Worker   shadow_frame->SetVRegReference(1, args.Get());
1049*795d594fSAndroid Build Coastguard Worker   UnstartedConstructorNewInstance0(self, shadow_frame.get(), &result, 0);
1050*795d594fSAndroid Build Coastguard Worker 
1051*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(result.GetL() != nullptr);
1052*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(self->IsExceptionPending());
1053*795d594fSAndroid Build Coastguard Worker 
1054*795d594fSAndroid Build Coastguard Worker   // Should be a new object.
1055*795d594fSAndroid Build Coastguard Worker   ASSERT_NE(result.GetL(), input.Get());
1056*795d594fSAndroid Build Coastguard Worker   // Should be of type Throwable.
1057*795d594fSAndroid Build Coastguard Worker   ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
1058*795d594fSAndroid Build Coastguard Worker   // Should have the right string.
1059*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::String> result_msg =
1060*795d594fSAndroid Build Coastguard Worker       reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
1061*795d594fSAndroid Build Coastguard Worker   EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
1062*795d594fSAndroid Build Coastguard Worker }
1063*795d594fSAndroid Build Coastguard Worker 
TEST_F(UnstartedRuntimeTest,IdentityHashCode)1064*795d594fSAndroid Build Coastguard Worker TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1065*795d594fSAndroid Build Coastguard Worker   Thread* self = Thread::Current();
1066*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(self);
1067*795d594fSAndroid Build Coastguard Worker   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, 0);
1068*795d594fSAndroid Build Coastguard Worker 
1069*795d594fSAndroid Build Coastguard Worker   JValue result;
1070*795d594fSAndroid Build Coastguard Worker   UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
1071*795d594fSAndroid Build Coastguard Worker 
1072*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(0, result.GetI());
1073*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(self->IsExceptionPending());
1074*795d594fSAndroid Build Coastguard Worker 
1075*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
1076*795d594fSAndroid Build Coastguard Worker   tmp->SetVRegReference(0, str);
1077*795d594fSAndroid Build Coastguard Worker   UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
1078*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(0, result.GetI());
1079*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1080*795d594fSAndroid Build Coastguard Worker   ASSERT_FALSE(self->IsExceptionPending());
1081*795d594fSAndroid Build Coastguard Worker }
1082*795d594fSAndroid Build Coastguard Worker 
1083*795d594fSAndroid Build Coastguard Worker }  // namespace interpreter
1084*795d594fSAndroid Build Coastguard Worker }  // namespace art
1085