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