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