• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.h"
18 
19 #include <limits>
20 #include <locale>
21 
22 #include "base/casts.h"
23 #include "base/enums.h"
24 #include "base/memory_tool.h"
25 #include "class_linker.h"
26 #include "class_root.h"
27 #include "common_runtime_test.h"
28 #include "dex/descriptors_names.h"
29 #include "dex/dex_instruction.h"
30 #include "handle.h"
31 #include "handle_scope-inl.h"
32 #include "interpreter/interpreter_common.h"
33 #include "mirror/array-alloc-inl.h"
34 #include "mirror/class-alloc-inl.h"
35 #include "mirror/class_loader.h"
36 #include "mirror/object-inl.h"
37 #include "mirror/object_array-alloc-inl.h"
38 #include "mirror/object_array-inl.h"
39 #include "mirror/string-inl.h"
40 #include "runtime.h"
41 #include "scoped_thread_state_change-inl.h"
42 #include "shadow_frame-inl.h"
43 #include "thread.h"
44 #include "transaction.h"
45 
46 namespace art {
47 namespace interpreter {
48 
49 // Deleter to be used with ShadowFrame::CreateDeoptimizedFrame objects.
50 struct DeoptShadowFrameDelete {
51   // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
operator ()art::interpreter::DeoptShadowFrameDelete52   void operator()(ShadowFrame* ptr) const {
53     if (ptr != nullptr) {
54       ShadowFrame::DeleteDeoptimizedFrame(ptr);
55     }
56   }
57 };
58 // Alias for std::unique_ptr<> that uses the above deleter.
59 using UniqueDeoptShadowFramePtr = std::unique_ptr<ShadowFrame, DeoptShadowFrameDelete>;
60 
61 class UnstartedRuntimeTest : public CommonRuntimeTest {
62  protected:
63   // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
64   // test friends.
65 
66   // Methods that intercept available libcore implementations.
67 #define UNSTARTED_DIRECT(Name, SigIgnored)                 \
68   static void Unstarted ## Name(Thread* self,              \
69                                 ShadowFrame* shadow_frame, \
70                                 JValue* result,            \
71                                 size_t arg_offset)         \
72       REQUIRES_SHARED(Locks::mutator_lock_) {        \
73     interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
74   }
75 #include "unstarted_runtime_list.h"
76   UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
77 #undef UNSTARTED_RUNTIME_DIRECT_LIST
78 #undef UNSTARTED_RUNTIME_JNI_LIST
79 #undef UNSTARTED_DIRECT
80 
81   // Methods that are native.
82 #define UNSTARTED_JNI(Name, SigIgnored)                       \
83   static void UnstartedJNI ## Name(Thread* self,              \
84                                    ArtMethod* method,         \
85                                    mirror::Object* receiver,  \
86                                    uint32_t* args,            \
87                                    JValue* result)            \
88       REQUIRES_SHARED(Locks::mutator_lock_) {           \
89     interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
90   }
91 #include "unstarted_runtime_list.h"
UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)92   UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
93 #undef UNSTARTED_RUNTIME_DIRECT_LIST
94 #undef UNSTARTED_RUNTIME_JNI_LIST
95 #undef UNSTARTED_JNI
96 
97   UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs,
98                                               ShadowFrame* link,
99                                               ArtMethod* method,
100                                               uint32_t dex_pc) {
101     return UniqueDeoptShadowFramePtr(
102         ShadowFrame::CreateDeoptimizedFrame(num_vregs, link, method, dex_pc));
103   }
104 
105   // Helpers for ArrayCopy.
106   //
107   // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
108   //       of three everywhere. That is enough to test all cases.
109 
CreateObjectArray(Thread * self,ObjPtr<mirror::Class> component_type,const StackHandleScope<3> & data)110   static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
111       Thread* self,
112       ObjPtr<mirror::Class> component_type,
113       const StackHandleScope<3>& data)
114       REQUIRES_SHARED(Locks::mutator_lock_) {
115     Runtime* runtime = Runtime::Current();
116     ObjPtr<mirror::Class> array_type =
117         runtime->GetClassLinker()->FindArrayClass(self, component_type);
118     CHECK(array_type != nullptr);
119     ObjPtr<mirror::ObjectArray<mirror::Object>> result =
120         mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
121     CHECK(result != nullptr);
122     for (size_t i = 0; i < 3; ++i) {
123       result->Set(static_cast<int32_t>(i), data.GetReference(i));
124       CHECK(!self->IsExceptionPending());
125     }
126     return result;
127   }
128 
CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,const StackHandleScope<3> & data)129   static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
130                                const StackHandleScope<3>& data)
131       REQUIRES_SHARED(Locks::mutator_lock_) {
132     CHECK_EQ(array->GetLength(), 3);
133     CHECK_EQ(data.NumberOfReferences(), 3U);
134     for (size_t i = 0; i < 3; ++i) {
135       EXPECT_OBJ_PTR_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
136     }
137   }
138 
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)139   void RunArrayCopy(Thread* self,
140                     ShadowFrame* tmp,
141                     bool expect_exception,
142                     ObjPtr<mirror::ObjectArray<mirror::Object>> src,
143                     int32_t src_pos,
144                     ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
145                     int32_t dst_pos,
146                     int32_t length)
147       REQUIRES_SHARED(Locks::mutator_lock_) {
148     JValue result;
149     tmp->SetVRegReference(0, src);
150     tmp->SetVReg(1, src_pos);
151     tmp->SetVRegReference(2, dst);
152     tmp->SetVReg(3, dst_pos);
153     tmp->SetVReg(4, length);
154     UnstartedSystemArraycopy(self, tmp, &result, 0);
155     bool exception_pending = self->IsExceptionPending();
156     EXPECT_EQ(exception_pending, expect_exception);
157     if (exception_pending) {
158       self->ClearException();
159     }
160   }
161 
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)162   void RunArrayCopy(Thread* self,
163                     ShadowFrame* tmp,
164                     bool expect_exception,
165                     ObjPtr<mirror::Class> src_component_class,
166                     ObjPtr<mirror::Class> dst_component_class,
167                     const StackHandleScope<3>& src_data,
168                     int32_t src_pos,
169                     const StackHandleScope<3>& dst_data,
170                     int32_t dst_pos,
171                     int32_t length,
172                     const StackHandleScope<3>& expected_result)
173       REQUIRES_SHARED(Locks::mutator_lock_) {
174     StackHandleScope<3> hs_misc(self);
175     Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
176 
177     Handle<mirror::ObjectArray<mirror::Object>> src_handle(
178         hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
179 
180     Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
181         hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
182 
183     RunArrayCopy(self,
184                  tmp,
185                  expect_exception,
186                  src_handle.Get(),
187                  src_pos,
188                  dst_handle.Get(),
189                  dst_pos,
190                  length);
191     CheckObjectArray(dst_handle.Get(), expected_result);
192   }
193 
TestCeilFloor(bool ceil,Thread * self,ShadowFrame * tmp,double const test_pairs[][2],size_t num_pairs)194   void TestCeilFloor(bool ceil,
195                      Thread* self,
196                      ShadowFrame* tmp,
197                      double const test_pairs[][2],
198                      size_t num_pairs)
199       REQUIRES_SHARED(Locks::mutator_lock_) {
200     for (size_t i = 0; i < num_pairs; ++i) {
201       tmp->SetVRegDouble(0, test_pairs[i][0]);
202 
203       JValue result;
204       if (ceil) {
205         UnstartedMathCeil(self, tmp, &result, 0);
206       } else {
207         UnstartedMathFloor(self, tmp, &result, 0);
208       }
209 
210       ASSERT_FALSE(self->IsExceptionPending());
211 
212       // We want precise results.
213       int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
214       int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
215       EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
216     }
217   }
218 
219   // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
220   // loading code doesn't work under transactions.
PrepareForAborts()221   void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
222     ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
223         Thread::Current(),
224         Transaction::kAbortExceptionSignature,
225         ScopedNullHandle<mirror::ClassLoader>());
226     CHECK(result != nullptr);
227   }
228 };
229 
TEST_F(UnstartedRuntimeTest,MemoryPeekByte)230 TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
231   Thread* self = Thread::Current();
232 
233   ScopedObjectAccess soa(self);
234   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
235   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
236   const uint8_t* base_ptr = base_array;
237 
238   JValue result;
239   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
240 
241   for (int32_t i = 0; i < kBaseLen; ++i) {
242     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
243 
244     UnstartedMemoryPeekByte(self, tmp.get(), &result, 0);
245 
246     EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
247   }
248 }
249 
TEST_F(UnstartedRuntimeTest,MemoryPeekShort)250 TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
251   Thread* self = Thread::Current();
252 
253   ScopedObjectAccess soa(self);
254   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
255   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
256   const uint8_t* base_ptr = base_array;
257 
258   JValue result;
259   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
260 
261   int32_t adjusted_length = kBaseLen - sizeof(int16_t);
262   for (int32_t i = 0; i < adjusted_length; ++i) {
263     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
264 
265     UnstartedMemoryPeekShort(self, tmp.get(), &result, 0);
266 
267     using unaligned_short __attribute__((__aligned__(1))) = int16_t;
268     const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
269     EXPECT_EQ(result.GetS(), *short_ptr);
270   }
271 }
272 
TEST_F(UnstartedRuntimeTest,MemoryPeekInt)273 TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
274   Thread* self = Thread::Current();
275 
276   ScopedObjectAccess soa(self);
277   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
278   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
279   const uint8_t* base_ptr = base_array;
280 
281   JValue result;
282   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
283 
284   int32_t adjusted_length = kBaseLen - sizeof(int32_t);
285   for (int32_t i = 0; i < adjusted_length; ++i) {
286     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
287 
288     UnstartedMemoryPeekInt(self, tmp.get(), &result, 0);
289 
290     using unaligned_int __attribute__((__aligned__(1))) = int32_t;
291     const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
292     EXPECT_EQ(result.GetI(), *int_ptr);
293   }
294 }
295 
TEST_F(UnstartedRuntimeTest,MemoryPeekLong)296 TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
297   Thread* self = Thread::Current();
298 
299   ScopedObjectAccess soa(self);
300   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
301   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
302   const uint8_t* base_ptr = base_array;
303 
304   JValue result;
305   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
306 
307   int32_t adjusted_length = kBaseLen - sizeof(int64_t);
308   for (int32_t i = 0; i < adjusted_length; ++i) {
309     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
310 
311     UnstartedMemoryPeekLong(self, tmp.get(), &result, 0);
312 
313     using unaligned_long __attribute__((__aligned__(1))) = int64_t;
314     const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
315     EXPECT_EQ(result.GetJ(), *long_ptr);
316   }
317 }
318 
TEST_F(UnstartedRuntimeTest,StringGetCharsNoCheck)319 TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
320   Thread* self = Thread::Current();
321 
322   ScopedObjectAccess soa(self);
323   StackHandleScope<2> hs(self);
324   // TODO: Actual UTF.
325   constexpr const char base_string[] = "abcdefghijklmnop";
326   Handle<mirror::String> h_test_string(hs.NewHandle(
327       mirror::String::AllocFromModifiedUtf8(self, base_string)));
328   constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
329   Handle<mirror::CharArray> h_char_array(hs.NewHandle(
330       mirror::CharArray::Alloc(self, kBaseLen)));
331   // A buffer so we can make sure we only modify the elements targetted.
332   uint16_t buf[kBaseLen];
333 
334   JValue result;
335   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
336 
337   for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
338     for (int32_t count = 0; count <= kBaseLen; ++count) {
339       for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
340         // Only do it when in bounds.
341         if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
342           tmp->SetVRegReference(0, h_test_string.Get());
343           tmp->SetVReg(1, start_index);
344           tmp->SetVReg(2, count);
345           tmp->SetVRegReference(3, h_char_array.Get());
346           tmp->SetVReg(3, trg_offset);
347 
348           // Copy the char_array into buf.
349           memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
350 
351           UnstartedStringCharAt(self, tmp.get(), &result, 0);
352 
353           uint16_t* data = h_char_array->GetData();
354 
355           bool success = true;
356 
357           // First segment should be unchanged.
358           for (int32_t i = 0; i < trg_offset; ++i) {
359             success = success && (data[i] == buf[i]);
360           }
361           // Second segment should be a copy.
362           for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
363             success = success && (data[i] == buf[i - trg_offset + start_index]);
364           }
365           // Third segment should be unchanged.
366           for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
367             success = success && (data[i] == buf[i]);
368           }
369 
370           EXPECT_TRUE(success);
371         }
372       }
373     }
374   }
375 }
376 
TEST_F(UnstartedRuntimeTest,StringCharAt)377 TEST_F(UnstartedRuntimeTest, StringCharAt) {
378   Thread* self = Thread::Current();
379 
380   ScopedObjectAccess soa(self);
381   // TODO: Actual UTF.
382   constexpr const char* base_string = "abcdefghijklmnop";
383   int32_t base_len = static_cast<int32_t>(strlen(base_string));
384   ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
385 
386   JValue result;
387   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
388 
389   for (int32_t i = 0; i < base_len; ++i) {
390     tmp->SetVRegReference(0, test_string);
391     tmp->SetVReg(1, i);
392 
393     UnstartedStringCharAt(self, tmp.get(), &result, 0);
394 
395     EXPECT_EQ(result.GetI(), base_string[i]);
396   }
397 }
398 
TEST_F(UnstartedRuntimeTest,StringInit)399 TEST_F(UnstartedRuntimeTest, StringInit) {
400   Thread* self = Thread::Current();
401   ScopedObjectAccess soa(self);
402   ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
403   ArtMethod* method =
404       klass->FindConstructor("(Ljava/lang/String;)V",
405                              Runtime::Current()->GetClassLinker()->GetImagePointerSize());
406   ASSERT_TRUE(method != nullptr);
407 
408   // create instruction data for invoke-direct {v0, v1} of method with fake index
409   uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
410 
411   JValue result;
412   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
413   const char* base_string = "hello_world";
414   StackHandleScope<2> hs(self);
415   Handle<mirror::String> string_arg =
416       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
417   Handle<mirror::String> reference_empty_string =
418       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
419   shadow_frame->SetVRegReference(0, reference_empty_string.Get());
420   shadow_frame->SetVRegReference(1, string_arg.Get());
421 
422   interpreter::DoCall<false, false>(method,
423                                     self,
424                                     *shadow_frame,
425                                     Instruction::At(inst_data),
426                                     inst_data[0],
427                                     &result);
428   ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
429   EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
430 
431   if (string_arg->IsCompressed() && string_result->IsCompressed()) {
432     EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
433                      string_arg->GetLength() * sizeof(uint8_t)), 0);
434   } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
435     EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
436                      string_arg->GetLength() * sizeof(uint16_t)), 0);
437   } else {
438     bool equal = true;
439     for (int i = 0; i < string_arg->GetLength(); ++i) {
440       if (string_arg->CharAt(i) != string_result->CharAt(i)) {
441         equal = false;
442         break;
443       }
444     }
445     EXPECT_EQ(equal, true);
446   }
447 }
448 
449 // Tests the exceptions that should be checked before modifying the destination.
450 // (Doesn't check the object vs primitive case ATM.)
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTestExceptions)451 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
452   Thread* self = Thread::Current();
453   ScopedObjectAccess soa(self);
454   JValue result;
455   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
456 
457   // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
458   //       allocate.
459   StackHandleScope<3> hs_misc(self);
460   Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
461 
462   StackHandleScope<3> hs_data(self);
463   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
464   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
465   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
466 
467   Handle<mirror::ObjectArray<mirror::Object>> array(
468       hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
469 
470   RunArrayCopy(self, tmp.get(), true, array.Get(), -1, array.Get(), 0, 0);
471   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), -1, 0);
472   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, -1);
473   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, 4);
474   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 1, 3);
475   RunArrayCopy(self, tmp.get(), true, array.Get(), 1, array.Get(), 0, 3);
476 
477   Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
478       hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
479   RunArrayCopy(self, tmp.get(), true, class_as_array.Get(), 0, array.Get(), 0, 0);
480   RunArrayCopy(self, tmp.get(), true, array.Get(), 0, class_as_array.Get(), 0, 0);
481 }
482 
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTest)483 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
484   Thread* self = Thread::Current();
485   ScopedObjectAccess soa(self);
486   JValue result;
487   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
488 
489   StackHandleScope<1> hs_object(self);
490   Handle<mirror::Class> object_class(hs_object.NewHandle(GetClassRoot<mirror::Object>()));
491 
492   // Simple test:
493   // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
494   {
495     StackHandleScope<3> hs_src(self);
496     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
497     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
498     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
499 
500     StackHandleScope<3> hs_dst(self);
501     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
502     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
503     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
504 
505     StackHandleScope<3> hs_expected(self);
506     hs_expected.NewHandle(hs_dst.GetReference(0));
507     hs_expected.NewHandle(hs_dst.GetReference(1));
508     hs_expected.NewHandle(hs_src.GetReference(1));
509 
510     RunArrayCopy(self,
511                  tmp.get(),
512                  false,
513                  object_class.Get(),
514                  object_class.Get(),
515                  hs_src,
516                  1,
517                  hs_dst,
518                  2,
519                  1,
520                  hs_expected);
521   }
522 
523   // Simple test:
524   // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
525   {
526     StackHandleScope<3> hs_src(self);
527     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
528     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
529     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
530 
531     StackHandleScope<3> hs_dst(self);
532     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
533     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
534     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
535 
536     StackHandleScope<3> hs_expected(self);
537     hs_expected.NewHandle(hs_dst.GetReference(0));
538     hs_expected.NewHandle(hs_src.GetReference(1));
539     hs_expected.NewHandle(hs_dst.GetReference(2));
540 
541     RunArrayCopy(self,
542                  tmp.get(),
543                  false,
544                  object_class.Get(),
545                  GetClassRoot<mirror::String>(),
546                  hs_src,
547                  1,
548                  hs_dst,
549                  1,
550                  1,
551                  hs_expected);
552   }
553 
554   // Simple test:
555   // [1,*,3] into [4,5,6] = [1,5,6] + exc
556   {
557     StackHandleScope<3> hs_src(self);
558     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
559     hs_src.NewHandle(GetClassRoot<mirror::String>());
560     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
561 
562     StackHandleScope<3> hs_dst(self);
563     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
564     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
565     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
566 
567     StackHandleScope<3> hs_expected(self);
568     hs_expected.NewHandle(hs_src.GetReference(0));
569     hs_expected.NewHandle(hs_dst.GetReference(1));
570     hs_expected.NewHandle(hs_dst.GetReference(2));
571 
572     RunArrayCopy(self,
573                  tmp.get(),
574                  true,
575                  object_class.Get(),
576                  GetClassRoot<mirror::String>(),
577                  hs_src,
578                  0,
579                  hs_dst,
580                  0,
581                  3,
582                  hs_expected);
583   }
584 }
585 
TEST_F(UnstartedRuntimeTest,IntegerParseIntTest)586 TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
587   Thread* self = Thread::Current();
588   ScopedObjectAccess soa(self);
589 
590   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
591 
592   // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
593   // suffixes).
594   constexpr const char* test_string = "-2147483646";
595   constexpr int32_t test_values[] = {
596                 6,
597                46,
598               646,
599              3646,
600             83646,
601            483646,
602           7483646,
603          47483646,
604         147483646,
605        2147483646,
606       -2147483646
607   };
608 
609   static_assert(arraysize(test_values) == 11U, "test_values");
610   CHECK_EQ(strlen(test_string), 11U);
611 
612   for (size_t i = 0; i <= 10; ++i) {
613     const char* test_value = &test_string[10 - i];
614 
615     StackHandleScope<1> hs_str(self);
616     Handle<mirror::String> h_str(
617         hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
618     ASSERT_NE(h_str.Get(), nullptr);
619     ASSERT_FALSE(self->IsExceptionPending());
620 
621     tmp->SetVRegReference(0, h_str.Get());
622 
623     JValue result;
624     UnstartedIntegerParseInt(self, tmp.get(), &result, 0);
625 
626     ASSERT_FALSE(self->IsExceptionPending());
627     EXPECT_EQ(result.GetI(), test_values[i]);
628   }
629 }
630 
631 // Right now the same as Integer.Parse
TEST_F(UnstartedRuntimeTest,LongParseLongTest)632 TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
633   Thread* self = Thread::Current();
634   ScopedObjectAccess soa(self);
635 
636   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
637 
638   // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
639   // suffixes).
640   constexpr const char* test_string = "-2147483646";
641   constexpr int64_t test_values[] = {
642                 6,
643                46,
644               646,
645              3646,
646             83646,
647            483646,
648           7483646,
649          47483646,
650         147483646,
651        2147483646,
652       -2147483646
653   };
654 
655   static_assert(arraysize(test_values) == 11U, "test_values");
656   CHECK_EQ(strlen(test_string), 11U);
657 
658   for (size_t i = 0; i <= 10; ++i) {
659     const char* test_value = &test_string[10 - i];
660 
661     StackHandleScope<1> hs_str(self);
662     Handle<mirror::String> h_str(
663         hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
664     ASSERT_NE(h_str.Get(), nullptr);
665     ASSERT_FALSE(self->IsExceptionPending());
666 
667     tmp->SetVRegReference(0, h_str.Get());
668 
669     JValue result;
670     UnstartedLongParseLong(self, tmp.get(), &result, 0);
671 
672     ASSERT_FALSE(self->IsExceptionPending());
673     EXPECT_EQ(result.GetJ(), test_values[i]);
674   }
675 }
676 
TEST_F(UnstartedRuntimeTest,Ceil)677 TEST_F(UnstartedRuntimeTest, Ceil) {
678   Thread* self = Thread::Current();
679   ScopedObjectAccess soa(self);
680 
681   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
682 
683   constexpr double nan = std::numeric_limits<double>::quiet_NaN();
684   constexpr double inf = std::numeric_limits<double>::infinity();
685   constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
686   constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
687   constexpr double test_pairs[][2] = {
688       { -0.0, -0.0 },
689       {  0.0,  0.0 },
690       { -0.5, -0.0 },
691       { -1.0, -1.0 },
692       {  0.5,  1.0 },
693       {  1.0,  1.0 },
694       {  nan,  nan },
695       {  inf,  inf },
696       { -inf, -inf },
697       {  ld1,  ld1 },
698       {  ld2,  ld2 }
699   };
700 
701   TestCeilFloor(/* ceil= */ true, self, tmp.get(), test_pairs, arraysize(test_pairs));
702 }
703 
TEST_F(UnstartedRuntimeTest,Floor)704 TEST_F(UnstartedRuntimeTest, Floor) {
705   Thread* self = Thread::Current();
706   ScopedObjectAccess soa(self);
707 
708   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
709 
710   constexpr double nan = std::numeric_limits<double>::quiet_NaN();
711   constexpr double inf = std::numeric_limits<double>::infinity();
712   constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
713   constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
714   constexpr double test_pairs[][2] = {
715       { -0.0, -0.0 },
716       {  0.0,  0.0 },
717       { -0.5, -1.0 },
718       { -1.0, -1.0 },
719       {  0.5,  0.0 },
720       {  1.0,  1.0 },
721       {  nan,  nan },
722       {  inf,  inf },
723       { -inf, -inf },
724       {  ld1,  ld1 },
725       {  ld2,  ld2 }
726   };
727 
728   TestCeilFloor(/* ceil= */ false, self, tmp.get(), test_pairs, arraysize(test_pairs));
729 }
730 
TEST_F(UnstartedRuntimeTest,ToLowerUpper)731 TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
732   Thread* self = Thread::Current();
733   ScopedObjectAccess soa(self);
734 
735   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
736 
737   std::locale c_locale("C");
738 
739   // Check ASCII.
740   for (uint32_t i = 0; i < 128; ++i) {
741     bool c_upper = std::isupper(static_cast<char>(i), c_locale);
742     bool c_lower = std::islower(static_cast<char>(i), c_locale);
743     EXPECT_FALSE(c_upper && c_lower) << i;
744 
745     // Check toLowerCase.
746     {
747       JValue result;
748       tmp->SetVReg(0, static_cast<int32_t>(i));
749       UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
750       ASSERT_FALSE(self->IsExceptionPending());
751       uint32_t lower_result = static_cast<uint32_t>(result.GetI());
752       if (c_lower) {
753         EXPECT_EQ(i, lower_result);
754       } else if (c_upper) {
755         EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
756                   lower_result);
757       } else {
758         EXPECT_EQ(i, lower_result);
759       }
760     }
761 
762     // Check toUpperCase.
763     {
764       JValue result2;
765       tmp->SetVReg(0, static_cast<int32_t>(i));
766       UnstartedCharacterToUpperCase(self, tmp.get(), &result2, 0);
767       ASSERT_FALSE(self->IsExceptionPending());
768       uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
769       if (c_upper) {
770         EXPECT_EQ(i, upper_result);
771       } else if (c_lower) {
772         EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
773                   upper_result);
774       } else {
775         EXPECT_EQ(i, upper_result);
776       }
777     }
778   }
779 
780   // Check abort for other things. Can't test all.
781 
782   PrepareForAborts();
783 
784   for (uint32_t i = 128; i < 256; ++i) {
785     {
786       JValue result;
787       tmp->SetVReg(0, static_cast<int32_t>(i));
788       Runtime::Current()->EnterTransactionMode();
789       UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
790       ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
791       Runtime::Current()->ExitTransactionMode();
792       ASSERT_TRUE(self->IsExceptionPending());
793     }
794     {
795       JValue result;
796       tmp->SetVReg(0, static_cast<int32_t>(i));
797       Runtime::Current()->EnterTransactionMode();
798       UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
799       ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
800       Runtime::Current()->ExitTransactionMode();
801       ASSERT_TRUE(self->IsExceptionPending());
802     }
803   }
804   for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
805     {
806       JValue result;
807       tmp->SetVReg(0, static_cast<int32_t>(i));
808       Runtime::Current()->EnterTransactionMode();
809       UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
810       ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
811       Runtime::Current()->ExitTransactionMode();
812       ASSERT_TRUE(self->IsExceptionPending());
813     }
814     {
815       JValue result;
816       tmp->SetVReg(0, static_cast<int32_t>(i));
817       Runtime::Current()->EnterTransactionMode();
818       UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
819       ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
820       Runtime::Current()->ExitTransactionMode();
821       ASSERT_TRUE(self->IsExceptionPending());
822     }
823   }
824 }
825 
TEST_F(UnstartedRuntimeTest,Sin)826 TEST_F(UnstartedRuntimeTest, Sin) {
827   Thread* self = Thread::Current();
828   ScopedObjectAccess soa(self);
829 
830   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
831 
832   // Test an important value, PI/6. That's the one we see in practice.
833   constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
834   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
835 
836   JValue result;
837   UnstartedMathSin(self, tmp.get(), &result, 0);
838 
839   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
840   EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
841 }
842 
TEST_F(UnstartedRuntimeTest,Cos)843 TEST_F(UnstartedRuntimeTest, Cos) {
844   Thread* self = Thread::Current();
845   ScopedObjectAccess soa(self);
846 
847   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
848 
849   // Test an important value, PI/6. That's the one we see in practice.
850   constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
851   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
852 
853   JValue result;
854   UnstartedMathCos(self, tmp.get(), &result, 0);
855 
856   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
857   EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
858 }
859 
TEST_F(UnstartedRuntimeTest,Pow)860 TEST_F(UnstartedRuntimeTest, Pow) {
861   Thread* self = Thread::Current();
862   ScopedObjectAccess soa(self);
863 
864   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
865 
866   // Test an important pair.
867   constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
868   constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
869 
870   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
871   tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
872 
873   JValue result;
874   UnstartedMathPow(self, tmp.get(), &result, 0);
875 
876   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
877   EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
878 }
879 
TEST_F(UnstartedRuntimeTest,IsAnonymousClass)880 TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
881   Thread* self = Thread::Current();
882   ScopedObjectAccess soa(self);
883 
884   JValue result;
885   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
886 
887   ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
888   shadow_frame->SetVRegReference(0, class_klass);
889   UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
890   EXPECT_EQ(result.GetZ(), 0);
891 
892   jobject class_loader = LoadDex("Nested");
893   StackHandleScope<1> hs(soa.Self());
894   Handle<mirror::ClassLoader> loader(
895       hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
896   ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
897   ASSERT_TRUE(c != nullptr);
898   shadow_frame->SetVRegReference(0, c);
899   UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
900   EXPECT_EQ(result.GetZ(), 1);
901 }
902 
TEST_F(UnstartedRuntimeTest,GetDeclaringClass)903 TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
904   Thread* self = Thread::Current();
905   ScopedObjectAccess soa(self);
906 
907   JValue result;
908   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
909 
910   jobject class_loader = LoadDex("Nested");
911   StackHandleScope<4> hs(self);
912   Handle<mirror::ClassLoader> loader(
913       hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
914 
915   Handle<mirror::Class> nested_klass(hs.NewHandle(
916       class_linker_->FindClass(soa.Self(), "LNested;", loader)));
917   Handle<mirror::Class> inner_klass(hs.NewHandle(
918       class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
919   Handle<mirror::Class> anon_klass(hs.NewHandle(
920       class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
921 
922   shadow_frame->SetVRegReference(0, nested_klass.Get());
923   UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
924   EXPECT_EQ(result.GetL(), nullptr);
925 
926   shadow_frame->SetVRegReference(0, inner_klass.Get());
927   UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
928   EXPECT_EQ(result.GetL(), nested_klass.Get());
929 
930   shadow_frame->SetVRegReference(0, anon_klass.Get());
931   UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
932   EXPECT_EQ(result.GetL(), nullptr);
933 }
934 
TEST_F(UnstartedRuntimeTest,ThreadLocalGet)935 TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
936   Thread* self = Thread::Current();
937   ScopedObjectAccess soa(self);
938 
939   JValue result;
940   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
941 
942   StackHandleScope<1> hs(self);
943   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
944 
945   // Positive test. See that We get something for float conversion.
946   {
947     Handle<mirror::Class> floating_decimal = hs.NewHandle(
948         class_linker->FindClass(self,
949                                 "Lsun/misc/FloatingDecimal;",
950                                 ScopedNullHandle<mirror::ClassLoader>()));
951     ASSERT_TRUE(floating_decimal != nullptr);
952     ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
953 
954     ArtMethod* caller_method = floating_decimal->FindClassMethod(
955         "getBinaryToASCIIBuffer",
956         "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
957         class_linker->GetImagePointerSize());
958     // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
959     ASSERT_TRUE(caller_method != nullptr);
960     ASSERT_TRUE(caller_method->IsDirect());
961     ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
962     UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
963     shadow_frame->SetLink(caller_frame.get());
964 
965     UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
966     EXPECT_TRUE(result.GetL() != nullptr);
967     EXPECT_FALSE(self->IsExceptionPending());
968 
969     shadow_frame->SetLink(nullptr);
970   }
971 
972   // Negative test.
973   PrepareForAborts();
974 
975   {
976     // Just use a method in Class.
977     ObjPtr<mirror::Class> class_class = GetClassRoot<mirror::Class>();
978     ArtMethod* caller_method =
979         &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
980     UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
981     shadow_frame->SetLink(caller_frame.get());
982 
983     Runtime::Current()->EnterTransactionMode();
984     UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
985     ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
986     Runtime::Current()->ExitTransactionMode();
987     ASSERT_TRUE(self->IsExceptionPending());
988     self->ClearException();
989 
990     shadow_frame->SetLink(nullptr);
991   }
992 }
993 
TEST_F(UnstartedRuntimeTest,FloatConversion)994 TEST_F(UnstartedRuntimeTest, FloatConversion) {
995   Thread* self = Thread::Current();
996   ScopedObjectAccess soa(self);
997 
998   StackHandleScope<1> hs(self);
999   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1000   Handle<mirror::Class> double_class = hs.NewHandle(
1001           class_linker->FindClass(self,
1002                                   "Ljava/lang/Double;",
1003                                   ScopedNullHandle<mirror::ClassLoader>()));
1004   ASSERT_TRUE(double_class != nullptr);
1005   ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1006 
1007   ArtMethod* method = double_class->FindClassMethod("toString",
1008                                                     "(D)Ljava/lang/String;",
1009                                                     class_linker->GetImagePointerSize());
1010   ASSERT_TRUE(method != nullptr);
1011   ASSERT_TRUE(method->IsDirect());
1012   ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
1013 
1014   // create instruction data for invoke-direct {v0, v1} of method with fake index
1015   uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
1016 
1017   JValue result;
1018   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
1019 
1020   shadow_frame->SetVRegDouble(0, 1.23);
1021   interpreter::DoCall<false, false>(method,
1022                                     self,
1023                                     *shadow_frame,
1024                                     Instruction::At(inst_data),
1025                                     inst_data[0],
1026                                     &result);
1027   ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
1028   ASSERT_TRUE(string_result != nullptr);
1029 
1030   std::string mod_utf = string_result->ToModifiedUtf8();
1031   EXPECT_EQ("1.23", mod_utf);
1032 }
1033 
TEST_F(UnstartedRuntimeTest,ThreadCurrentThread)1034 TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1035   Thread* self = Thread::Current();
1036   ScopedObjectAccess soa(self);
1037 
1038   JValue result;
1039   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
1040 
1041   StackHandleScope<1> hs(self);
1042   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1043   Handle<mirror::Class> thread_class = hs.NewHandle(
1044       class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1045   ASSERT_TRUE(thread_class.Get() != nullptr);
1046   ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1047 
1048   // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1049   // be recreated at runtime).
1050   PrepareForAborts();
1051 
1052   {
1053     Runtime::Current()->EnterTransactionMode();
1054     UnstartedThreadCurrentThread(self, shadow_frame.get(), &result, 0);
1055     ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
1056     Runtime::Current()->ExitTransactionMode();
1057     ASSERT_TRUE(self->IsExceptionPending());
1058     self->ClearException();
1059   }
1060 }
1061 
TEST_F(UnstartedRuntimeTest,LogManager)1062 TEST_F(UnstartedRuntimeTest, LogManager) {
1063   Thread* self = Thread::Current();
1064   ScopedObjectAccess soa(self);
1065 
1066   StackHandleScope<1> hs(self);
1067   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1068   Handle<mirror::Class> log_manager_class = hs.NewHandle(
1069       class_linker->FindClass(self,
1070                               "Ljava/util/logging/LogManager;",
1071                               ScopedNullHandle<mirror::ClassLoader>()));
1072   ASSERT_TRUE(log_manager_class.Get() != nullptr);
1073   ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1074 }
1075 
1076 class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1077  public:
1078   template <typename T>
RunTest(T & runner,bool in_transaction,bool should_succeed)1079   void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1080     Thread* self = Thread::Current();
1081     ScopedObjectAccess soa(self);
1082 
1083     // Ensure that Class is initialized.
1084     {
1085       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1086       StackHandleScope<1> hs(self);
1087       Handle<mirror::Class> h_class = hs.NewHandle(GetClassRoot<mirror::Class>());
1088       CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1089     }
1090 
1091     // A selection of classes from different core classpath components.
1092     constexpr const char* kTestCases[] = {
1093         "java.net.CookieManager",  // From libcore.
1094         "dalvik.system.ClassExt",  // From libart.
1095     };
1096 
1097     if (in_transaction) {
1098       // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1099       // classes isn't transactional. Load them ahead of time.
1100       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1101       for (const char* name : kTestCases) {
1102         class_linker->FindClass(self,
1103                                 DotToDescriptor(name).c_str(),
1104                                 ScopedNullHandle<mirror::ClassLoader>());
1105         CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1106       }
1107     }
1108 
1109     if (!should_succeed) {
1110       // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1111       // be recreated at runtime).
1112       PrepareForAborts();
1113     }
1114 
1115     JValue result;
1116     UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
1117 
1118     for (const char* name : kTestCases) {
1119       ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
1120       CHECK(name_string != nullptr);
1121 
1122       if (in_transaction) {
1123         Runtime::Current()->EnterTransactionMode();
1124       }
1125       CHECK(!self->IsExceptionPending());
1126 
1127       runner(self, shadow_frame.get(), name_string, &result);
1128 
1129       if (should_succeed) {
1130         CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1131         CHECK(result.GetL() != nullptr) << name;
1132       } else {
1133         CHECK(self->IsExceptionPending()) << name;
1134         if (in_transaction) {
1135           ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
1136         }
1137         self->ClearException();
1138       }
1139 
1140       if (in_transaction) {
1141         Runtime::Current()->ExitTransactionMode();
1142       }
1143     }
1144   }
1145 
GetBootClassLoader()1146   mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1147     Thread* self = Thread::Current();
1148     StackHandleScope<2> hs(self);
1149     MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1150 
1151     {
1152       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1153 
1154       // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1155       Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1156           class_linker->FindClass(self,
1157                                   "Ljava/lang/BootClassLoader;",
1158                                   ScopedNullHandle<mirror::ClassLoader>()));
1159       CHECK(boot_cp_class != nullptr);
1160       CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1161 
1162       boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1163       CHECK(boot_cp != nullptr);
1164 
1165       ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1166           "()V", class_linker->GetImagePointerSize());
1167       CHECK(boot_cp_init != nullptr);
1168 
1169       JValue result;
1170       UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, boot_cp_init, 0);
1171       shadow_frame->SetVRegReference(0, boot_cp.Get());
1172 
1173       // create instruction data for invoke-direct {v0} of method with fake index
1174       uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
1175 
1176       interpreter::DoCall<false, false>(boot_cp_init,
1177                                         self,
1178                                         *shadow_frame,
1179                                         Instruction::At(inst_data),
1180                                         inst_data[0],
1181                                         &result);
1182       CHECK(!self->IsExceptionPending());
1183     }
1184 
1185     return boot_cp.Get();
1186   }
1187 };
1188 
TEST_F(UnstartedClassForNameTest,ClassForName)1189 TEST_F(UnstartedClassForNameTest, ClassForName) {
1190   auto runner = [](Thread* self,
1191                    ShadowFrame* shadow_frame,
1192                    ObjPtr<mirror::String> name,
1193                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
1194     shadow_frame->SetVRegReference(0, name);
1195     UnstartedClassForName(self, shadow_frame, result, 0);
1196   };
1197   RunTest(runner, false, true);
1198 }
1199 
TEST_F(UnstartedClassForNameTest,ClassForNameLong)1200 TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
1201   auto runner = [](Thread* self,
1202                    ShadowFrame* shadow_frame,
1203                    ObjPtr<mirror::String> name,
1204                    JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
1205     shadow_frame->SetVRegReference(0, name);
1206     shadow_frame->SetVReg(1, 0);
1207     shadow_frame->SetVRegReference(2, nullptr);
1208     UnstartedClassForNameLong(self, shadow_frame, result, 0);
1209   };
1210   RunTest(runner, false, true);
1211 }
1212 
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoader)1213 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1214   Thread* self = Thread::Current();
1215   ScopedObjectAccess soa(self);
1216 
1217   StackHandleScope<1> hs(self);
1218   Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1219 
1220   auto runner = [&](Thread* th,
1221                     ShadowFrame* shadow_frame,
1222                     ObjPtr<mirror::String> name,
1223                     JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
1224     shadow_frame->SetVRegReference(0, name);
1225     shadow_frame->SetVReg(1, 0);
1226     shadow_frame->SetVRegReference(2, boot_cp.Get());
1227     UnstartedClassForNameLong(th, shadow_frame, result, 0);
1228   };
1229   RunTest(runner, false, true);
1230 }
1231 
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoaderTransaction)1232 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1233   Thread* self = Thread::Current();
1234   ScopedObjectAccess soa(self);
1235 
1236   StackHandleScope<1> hs(self);
1237   Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1238 
1239   auto runner = [&](Thread* th,
1240                     ShadowFrame* shadow_frame,
1241                     ObjPtr<mirror::String> name,
1242                     JValue* result)
1243       REQUIRES_SHARED(Locks::mutator_lock_) {
1244     shadow_frame->SetVRegReference(0, name);
1245     shadow_frame->SetVReg(1, 0);
1246     shadow_frame->SetVRegReference(2, boot_cp.Get());
1247     UnstartedClassForNameLong(th, shadow_frame, result, 0);
1248   };
1249   RunTest(runner, true, true);
1250 }
1251 
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoaderFail)1252 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1253   Thread* self = Thread::Current();
1254   ScopedObjectAccess soa(self);
1255 
1256   StackHandleScope<2> hs(self);
1257   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1258   jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1259   ASSERT_TRUE(path_jobj != nullptr);
1260   Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1261       self->DecodeJObject(path_jobj)->AsClassLoader());
1262 
1263   auto runner = [&](Thread* th,
1264                     ShadowFrame* shadow_frame,
1265                     ObjPtr<mirror::String> name,
1266                     JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
1267     shadow_frame->SetVRegReference(0, name);
1268     shadow_frame->SetVReg(1, 0);
1269     shadow_frame->SetVRegReference(2, path_cp.Get());
1270     UnstartedClassForNameLong(th, shadow_frame, result, 0);
1271   };
1272   RunTest(runner, true, false);
1273 }
1274 
TEST_F(UnstartedRuntimeTest,ClassGetSignatureAnnotation)1275 TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1276   Thread* self = Thread::Current();
1277   ScopedObjectAccess soa(self);
1278 
1279   StackHandleScope<1> hs(self);
1280   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1281   Handle<mirror::Class> list_class = hs.NewHandle(
1282       class_linker->FindClass(self,
1283                               "Ljava/util/List;",
1284                               ScopedNullHandle<mirror::ClassLoader>()));
1285   ASSERT_TRUE(list_class.Get() != nullptr);
1286   ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1287 
1288   JValue result;
1289   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
1290 
1291   shadow_frame->SetVRegReference(0, list_class.Get());
1292   UnstartedClassGetSignatureAnnotation(self, shadow_frame.get(), &result, 0);
1293   ASSERT_TRUE(result.GetL() != nullptr);
1294   ASSERT_FALSE(self->IsExceptionPending());
1295 
1296   ASSERT_TRUE(result.GetL()->IsObjectArray());
1297   ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1298       result.GetL()->AsObjectArray<mirror::Object>();
1299   std::ostringstream oss;
1300   for (int32_t i = 0; i != array->GetLength(); ++i) {
1301     ObjPtr<mirror::Object> elem = array->Get(i);
1302     ASSERT_TRUE(elem != nullptr);
1303     ASSERT_TRUE(elem->IsString());
1304     oss << elem->AsString()->ToModifiedUtf8();
1305   }
1306   std::string output_string = oss.str();
1307   ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1308 }
1309 
TEST_F(UnstartedRuntimeTest,ConstructorNewInstance0)1310 TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1311   Thread* self = Thread::Current();
1312   ScopedObjectAccess soa(self);
1313 
1314   StackHandleScope<4> hs(self);
1315   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1316 
1317   // Get Throwable.
1318   Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
1319   ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1320 
1321   // Get an input object.
1322   Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1323 
1324   // Find the constructor.
1325   ArtMethod* throw_cons = throw_class->FindConstructor(
1326       "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
1327   ASSERT_TRUE(throw_cons != nullptr);
1328   Handle<mirror::Constructor> cons;
1329   if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1330      cons = hs.NewHandle(
1331         mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1332     ASSERT_TRUE(cons != nullptr);
1333   } else {
1334     cons = hs.NewHandle(
1335         mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1336     ASSERT_TRUE(cons != nullptr);
1337   }
1338 
1339   Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
1340       mirror::ObjectArray<mirror::Object>::Alloc(
1341           self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
1342   ASSERT_TRUE(args != nullptr);
1343   args->Set(0, input.Get());
1344 
1345   // OK, we're ready now.
1346   JValue result;
1347   UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
1348   shadow_frame->SetVRegReference(0, cons.Get());
1349   shadow_frame->SetVRegReference(1, args.Get());
1350   UnstartedConstructorNewInstance0(self, shadow_frame.get(), &result, 0);
1351 
1352   ASSERT_TRUE(result.GetL() != nullptr);
1353   ASSERT_FALSE(self->IsExceptionPending());
1354 
1355   // Should be a new object.
1356   ASSERT_NE(result.GetL(), input.Get());
1357   // Should be of type Throwable.
1358   ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
1359   // Should have the right string.
1360   ObjPtr<mirror::String> result_msg =
1361       reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
1362   EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
1363 }
1364 
TEST_F(UnstartedRuntimeTest,IdentityHashCode)1365 TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1366   Thread* self = Thread::Current();
1367   ScopedObjectAccess soa(self);
1368   UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
1369 
1370   JValue result;
1371   UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
1372 
1373   EXPECT_EQ(0, result.GetI());
1374   ASSERT_FALSE(self->IsExceptionPending());
1375 
1376   ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
1377   tmp->SetVRegReference(0, str);
1378   UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
1379   EXPECT_NE(0, result.GetI());
1380   EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1381   ASSERT_FALSE(self->IsExceptionPending());
1382 }
1383 
1384 }  // namespace interpreter
1385 }  // namespace art
1386