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