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