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