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