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