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/memory_tool.h"
24 #include "class_linker.h"
25 #include "common_runtime_test.h"
26 #include "dex_instruction.h"
27 #include "handle.h"
28 #include "handle_scope-inl.h"
29 #include "interpreter/interpreter_common.h"
30 #include "mirror/class_loader.h"
31 #include "mirror/string-inl.h"
32 #include "runtime.h"
33 #include "scoped_thread_state_change.h"
34 #include "thread.h"
35 #include "transaction.h"
36 
37 namespace art {
38 namespace interpreter {
39 
40 class UnstartedRuntimeTest : public CommonRuntimeTest {
41  protected:
42   // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
43   // test friends.
44 
45   // Methods that intercept available libcore implementations.
46 #define UNSTARTED_DIRECT(Name, SigIgnored)                 \
47   static void Unstarted ## Name(Thread* self,              \
48                                 ShadowFrame* shadow_frame, \
49                                 JValue* result,            \
50                                 size_t arg_offset)         \
51       SHARED_REQUIRES(Locks::mutator_lock_) {        \
52     interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
53   }
54 #include "unstarted_runtime_list.h"
55   UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
56 #undef UNSTARTED_RUNTIME_DIRECT_LIST
57 #undef UNSTARTED_RUNTIME_JNI_LIST
58 #undef UNSTARTED_DIRECT
59 
60   // Methods that are native.
61 #define UNSTARTED_JNI(Name, SigIgnored)                       \
62   static void UnstartedJNI ## Name(Thread* self,              \
63                                    ArtMethod* method,         \
64                                    mirror::Object* receiver,  \
65                                    uint32_t* args,            \
66                                    JValue* result)            \
67       SHARED_REQUIRES(Locks::mutator_lock_) {           \
68     interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
69   }
70 #include "unstarted_runtime_list.h"
UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)71   UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
72 #undef UNSTARTED_RUNTIME_DIRECT_LIST
73 #undef UNSTARTED_RUNTIME_JNI_LIST
74 #undef UNSTARTED_JNI
75 
76   // Helpers for ArrayCopy.
77   //
78   // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
79   //       of three everywhere. That is enough to test all cases.
80 
81   static mirror::ObjectArray<mirror::Object>* CreateObjectArray(
82       Thread* self,
83       mirror::Class* component_type,
84       const StackHandleScope<3>& data)
85       SHARED_REQUIRES(Locks::mutator_lock_) {
86     Runtime* runtime = Runtime::Current();
87     mirror::Class* array_type = runtime->GetClassLinker()->FindArrayClass(self, &component_type);
88     CHECK(array_type != nullptr);
89     mirror::ObjectArray<mirror::Object>* result =
90         mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
91     CHECK(result != nullptr);
92     for (size_t i = 0; i < 3; ++i) {
93       result->Set(static_cast<int32_t>(i), data.GetReference(i));
94       CHECK(!self->IsExceptionPending());
95     }
96     return result;
97   }
98 
CheckObjectArray(mirror::ObjectArray<mirror::Object> * array,const StackHandleScope<3> & data)99   static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array,
100                                const StackHandleScope<3>& data)
101       SHARED_REQUIRES(Locks::mutator_lock_) {
102     CHECK_EQ(array->GetLength(), 3);
103     CHECK_EQ(data.NumberOfReferences(), 3U);
104     for (size_t i = 0; i < 3; ++i) {
105       EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
106     }
107   }
108 
RunArrayCopy(Thread * self,ShadowFrame * tmp,bool expect_exception,mirror::ObjectArray<mirror::Object> * src,int32_t src_pos,mirror::ObjectArray<mirror::Object> * dst,int32_t dst_pos,int32_t length)109   void RunArrayCopy(Thread* self,
110                     ShadowFrame* tmp,
111                     bool expect_exception,
112                     mirror::ObjectArray<mirror::Object>* src,
113                     int32_t src_pos,
114                     mirror::ObjectArray<mirror::Object>* dst,
115                     int32_t dst_pos,
116                     int32_t length)
117       SHARED_REQUIRES(Locks::mutator_lock_) {
118     JValue result;
119     tmp->SetVRegReference(0, src);
120     tmp->SetVReg(1, src_pos);
121     tmp->SetVRegReference(2, dst);
122     tmp->SetVReg(3, dst_pos);
123     tmp->SetVReg(4, length);
124     UnstartedSystemArraycopy(self, tmp, &result, 0);
125     bool exception_pending = self->IsExceptionPending();
126     EXPECT_EQ(exception_pending, expect_exception);
127     if (exception_pending) {
128       self->ClearException();
129     }
130   }
131 
RunArrayCopy(Thread * self,ShadowFrame * tmp,bool expect_exception,mirror::Class * src_component_class,mirror::Class * dst_component_class,const StackHandleScope<3> & src_data,int32_t src_pos,const StackHandleScope<3> & dst_data,int32_t dst_pos,int32_t length,const StackHandleScope<3> & expected_result)132   void RunArrayCopy(Thread* self,
133                     ShadowFrame* tmp,
134                     bool expect_exception,
135                     mirror::Class* src_component_class,
136                     mirror::Class* dst_component_class,
137                     const StackHandleScope<3>& src_data,
138                     int32_t src_pos,
139                     const StackHandleScope<3>& dst_data,
140                     int32_t dst_pos,
141                     int32_t length,
142                     const StackHandleScope<3>& expected_result)
143       SHARED_REQUIRES(Locks::mutator_lock_) {
144     StackHandleScope<3> hs_misc(self);
145     Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
146 
147     Handle<mirror::ObjectArray<mirror::Object>> src_handle(
148         hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
149 
150     Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
151         hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
152 
153     RunArrayCopy(self,
154                  tmp,
155                  expect_exception,
156                  src_handle.Get(),
157                  src_pos,
158                  dst_handle.Get(),
159                  dst_pos,
160                  length);
161     CheckObjectArray(dst_handle.Get(), expected_result);
162   }
163 
TestCeilFloor(bool ceil,Thread * self,ShadowFrame * tmp,double const test_pairs[][2],size_t num_pairs)164   void TestCeilFloor(bool ceil,
165                      Thread* self,
166                      ShadowFrame* tmp,
167                      double const test_pairs[][2],
168                      size_t num_pairs)
169       SHARED_REQUIRES(Locks::mutator_lock_) {
170     for (size_t i = 0; i < num_pairs; ++i) {
171       tmp->SetVRegDouble(0, test_pairs[i][0]);
172 
173       JValue result;
174       if (ceil) {
175         UnstartedMathCeil(self, tmp, &result, 0);
176       } else {
177         UnstartedMathFloor(self, tmp, &result, 0);
178       }
179 
180       ASSERT_FALSE(self->IsExceptionPending());
181 
182       // We want precise results.
183       int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
184       int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
185       EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
186     }
187   }
188 
189   // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
190   // loading code doesn't work under transactions.
PrepareForAborts()191   void PrepareForAborts() SHARED_REQUIRES(Locks::mutator_lock_) {
192     mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass(
193         Thread::Current(),
194         Transaction::kAbortExceptionSignature,
195         ScopedNullHandle<mirror::ClassLoader>());
196     CHECK(result != nullptr);
197   }
198 };
199 
TEST_F(UnstartedRuntimeTest,MemoryPeekByte)200 TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
201   Thread* self = Thread::Current();
202 
203   ScopedObjectAccess soa(self);
204   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
205   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
206   const uint8_t* base_ptr = base_array;
207 
208   JValue result;
209   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
210 
211   for (int32_t i = 0; i < kBaseLen; ++i) {
212     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
213 
214     UnstartedMemoryPeekByte(self, tmp, &result, 0);
215 
216     EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
217   }
218 
219   ShadowFrame::DeleteDeoptimizedFrame(tmp);
220 }
221 
TEST_F(UnstartedRuntimeTest,MemoryPeekShort)222 TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
223   Thread* self = Thread::Current();
224 
225   ScopedObjectAccess soa(self);
226   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
227   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
228   const uint8_t* base_ptr = base_array;
229 
230   JValue result;
231   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
232 
233   int32_t adjusted_length = kBaseLen - sizeof(int16_t);
234   for (int32_t i = 0; i < adjusted_length; ++i) {
235     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
236 
237     UnstartedMemoryPeekShort(self, tmp, &result, 0);
238 
239     typedef int16_t unaligned_short __attribute__ ((aligned (1)));
240     const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
241     EXPECT_EQ(result.GetS(), *short_ptr);
242   }
243 
244   ShadowFrame::DeleteDeoptimizedFrame(tmp);
245 }
246 
TEST_F(UnstartedRuntimeTest,MemoryPeekInt)247 TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
248   Thread* self = Thread::Current();
249 
250   ScopedObjectAccess soa(self);
251   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
252   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
253   const uint8_t* base_ptr = base_array;
254 
255   JValue result;
256   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
257 
258   int32_t adjusted_length = kBaseLen - sizeof(int32_t);
259   for (int32_t i = 0; i < adjusted_length; ++i) {
260     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
261 
262     UnstartedMemoryPeekInt(self, tmp, &result, 0);
263 
264     typedef int32_t unaligned_int __attribute__ ((aligned (1)));
265     const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
266     EXPECT_EQ(result.GetI(), *int_ptr);
267   }
268 
269   ShadowFrame::DeleteDeoptimizedFrame(tmp);
270 }
271 
TEST_F(UnstartedRuntimeTest,MemoryPeekLong)272 TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
273   Thread* self = Thread::Current();
274 
275   ScopedObjectAccess soa(self);
276   constexpr const uint8_t base_array[] = "abcdefghijklmnop";
277   constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
278   const uint8_t* base_ptr = base_array;
279 
280   JValue result;
281   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
282 
283   int32_t adjusted_length = kBaseLen - sizeof(int64_t);
284   for (int32_t i = 0; i < adjusted_length; ++i) {
285     tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
286 
287     UnstartedMemoryPeekLong(self, tmp, &result, 0);
288 
289     typedef int64_t unaligned_long __attribute__ ((aligned (1)));
290     const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
291     EXPECT_EQ(result.GetJ(), *long_ptr);
292   }
293 
294   ShadowFrame::DeleteDeoptimizedFrame(tmp);
295 }
296 
TEST_F(UnstartedRuntimeTest,StringGetCharsNoCheck)297 TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
298   Thread* self = Thread::Current();
299 
300   ScopedObjectAccess soa(self);
301   StackHandleScope<2> hs(self);
302   // TODO: Actual UTF.
303   constexpr const char base_string[] = "abcdefghijklmnop";
304   Handle<mirror::String> h_test_string(hs.NewHandle(
305       mirror::String::AllocFromModifiedUtf8(self, base_string)));
306   constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
307   Handle<mirror::CharArray> h_char_array(hs.NewHandle(
308       mirror::CharArray::Alloc(self, kBaseLen)));
309   // A buffer so we can make sure we only modify the elements targetted.
310   uint16_t buf[kBaseLen];
311 
312   JValue result;
313   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
314 
315   for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
316     for (int32_t count = 0; count <= kBaseLen; ++count) {
317       for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
318         // Only do it when in bounds.
319         if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
320           tmp->SetVRegReference(0, h_test_string.Get());
321           tmp->SetVReg(1, start_index);
322           tmp->SetVReg(2, count);
323           tmp->SetVRegReference(3, h_char_array.Get());
324           tmp->SetVReg(3, trg_offset);
325 
326           // Copy the char_array into buf.
327           memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
328 
329           UnstartedStringCharAt(self, tmp, &result, 0);
330 
331           uint16_t* data = h_char_array->GetData();
332 
333           bool success = true;
334 
335           // First segment should be unchanged.
336           for (int32_t i = 0; i < trg_offset; ++i) {
337             success = success && (data[i] == buf[i]);
338           }
339           // Second segment should be a copy.
340           for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
341             success = success && (data[i] == buf[i - trg_offset + start_index]);
342           }
343           // Third segment should be unchanged.
344           for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
345             success = success && (data[i] == buf[i]);
346           }
347 
348           EXPECT_TRUE(success);
349         }
350       }
351     }
352   }
353 
354   ShadowFrame::DeleteDeoptimizedFrame(tmp);
355 }
356 
TEST_F(UnstartedRuntimeTest,StringCharAt)357 TEST_F(UnstartedRuntimeTest, StringCharAt) {
358   Thread* self = Thread::Current();
359 
360   ScopedObjectAccess soa(self);
361   // TODO: Actual UTF.
362   constexpr const char* base_string = "abcdefghijklmnop";
363   int32_t base_len = static_cast<int32_t>(strlen(base_string));
364   mirror::String* test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
365 
366   JValue result;
367   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
368 
369   for (int32_t i = 0; i < base_len; ++i) {
370     tmp->SetVRegReference(0, test_string);
371     tmp->SetVReg(1, i);
372 
373     UnstartedStringCharAt(self, tmp, &result, 0);
374 
375     EXPECT_EQ(result.GetI(), base_string[i]);
376   }
377 
378   ShadowFrame::DeleteDeoptimizedFrame(tmp);
379 }
380 
TEST_F(UnstartedRuntimeTest,StringInit)381 TEST_F(UnstartedRuntimeTest, StringInit) {
382   Thread* self = Thread::Current();
383   ScopedObjectAccess soa(self);
384   mirror::Class* klass = mirror::String::GetJavaLangString();
385   ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V",
386                                                       sizeof(void*));
387 
388   // create instruction data for invoke-direct {v0, v1} of method with fake index
389   uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
390   const Instruction* inst = Instruction::At(inst_data);
391 
392   JValue result;
393   ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
394   const char* base_string = "hello_world";
395   mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string);
396   mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, "");
397   shadow_frame->SetVRegReference(0, reference_empty_string);
398   shadow_frame->SetVRegReference(1, string_arg);
399 
400   interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
401   mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL());
402   EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
403   EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
404                    string_arg->GetLength() * sizeof(uint16_t)), 0);
405 
406   ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
407 }
408 
409 // Tests the exceptions that should be checked before modifying the destination.
410 // (Doesn't check the object vs primitive case ATM.)
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTestExceptions)411 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
412   Thread* self = Thread::Current();
413   ScopedObjectAccess soa(self);
414   JValue result;
415   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
416 
417   // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
418   //       allocate.
419   StackHandleScope<2> hs_misc(self);
420   Handle<mirror::Class> object_class(
421       hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
422 
423   StackHandleScope<3> hs_data(self);
424   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
425   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
426   hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
427 
428   Handle<mirror::ObjectArray<mirror::Object>> array(
429       hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
430 
431   RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
432   RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
433   RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
434   RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
435   RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
436   RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
437 
438   mirror::ObjectArray<mirror::Object>* class_as_array =
439       reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get());
440   RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0);
441   RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0);
442 
443   ShadowFrame::DeleteDeoptimizedFrame(tmp);
444 }
445 
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTest)446 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
447   Thread* self = Thread::Current();
448   ScopedObjectAccess soa(self);
449   JValue result;
450   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
451 
452   StackHandleScope<1> hs_object(self);
453   Handle<mirror::Class> object_class(
454       hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
455 
456   // Simple test:
457   // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
458   {
459     StackHandleScope<3> hs_src(self);
460     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
461     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
462     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
463 
464     StackHandleScope<3> hs_dst(self);
465     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
466     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
467     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
468 
469     StackHandleScope<3> hs_expected(self);
470     hs_expected.NewHandle(hs_dst.GetReference(0));
471     hs_expected.NewHandle(hs_dst.GetReference(1));
472     hs_expected.NewHandle(hs_src.GetReference(1));
473 
474     RunArrayCopy(self,
475                  tmp,
476                  false,
477                  object_class.Get(),
478                  object_class.Get(),
479                  hs_src,
480                  1,
481                  hs_dst,
482                  2,
483                  1,
484                  hs_expected);
485   }
486 
487   // Simple test:
488   // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6]  (with dst String[])
489   {
490     StackHandleScope<3> hs_src(self);
491     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
492     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
493     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
494 
495     StackHandleScope<3> hs_dst(self);
496     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
497     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
498     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
499 
500     StackHandleScope<3> hs_expected(self);
501     hs_expected.NewHandle(hs_dst.GetReference(0));
502     hs_expected.NewHandle(hs_src.GetReference(1));
503     hs_expected.NewHandle(hs_dst.GetReference(2));
504 
505     RunArrayCopy(self,
506                  tmp,
507                  false,
508                  object_class.Get(),
509                  mirror::String::GetJavaLangString(),
510                  hs_src,
511                  1,
512                  hs_dst,
513                  1,
514                  1,
515                  hs_expected);
516   }
517 
518   // Simple test:
519   // [1,*,3] into [4,5,6] = [1,5,6] + exc
520   {
521     StackHandleScope<3> hs_src(self);
522     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
523     hs_src.NewHandle(mirror::String::GetJavaLangString());
524     hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
525 
526     StackHandleScope<3> hs_dst(self);
527     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
528     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
529     hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
530 
531     StackHandleScope<3> hs_expected(self);
532     hs_expected.NewHandle(hs_src.GetReference(0));
533     hs_expected.NewHandle(hs_dst.GetReference(1));
534     hs_expected.NewHandle(hs_dst.GetReference(2));
535 
536     RunArrayCopy(self,
537                  tmp,
538                  true,
539                  object_class.Get(),
540                  mirror::String::GetJavaLangString(),
541                  hs_src,
542                  0,
543                  hs_dst,
544                  0,
545                  3,
546                  hs_expected);
547   }
548 
549   ShadowFrame::DeleteDeoptimizedFrame(tmp);
550 }
551 
TEST_F(UnstartedRuntimeTest,IntegerParseIntTest)552 TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
553   Thread* self = Thread::Current();
554   ScopedObjectAccess soa(self);
555 
556   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
557 
558   // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
559   // suffixes).
560   constexpr const char* test_string = "-2147483646";
561   constexpr int32_t test_values[] = {
562                 6,
563                46,
564               646,
565              3646,
566             83646,
567            483646,
568           7483646,
569          47483646,
570         147483646,
571        2147483646,
572       -2147483646
573   };
574 
575   static_assert(arraysize(test_values) == 11U, "test_values");
576   CHECK_EQ(strlen(test_string), 11U);
577 
578   for (size_t i = 0; i <= 10; ++i) {
579     const char* test_value = &test_string[10 - i];
580 
581     StackHandleScope<1> hs_str(self);
582     Handle<mirror::String> h_str(
583         hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
584     ASSERT_NE(h_str.Get(), nullptr);
585     ASSERT_FALSE(self->IsExceptionPending());
586 
587     tmp->SetVRegReference(0, h_str.Get());
588 
589     JValue result;
590     UnstartedIntegerParseInt(self, tmp, &result, 0);
591 
592     ASSERT_FALSE(self->IsExceptionPending());
593     EXPECT_EQ(result.GetI(), test_values[i]);
594   }
595 
596   ShadowFrame::DeleteDeoptimizedFrame(tmp);
597 }
598 
599 // Right now the same as Integer.Parse
TEST_F(UnstartedRuntimeTest,LongParseLongTest)600 TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
601   Thread* self = Thread::Current();
602   ScopedObjectAccess soa(self);
603 
604   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
605 
606   // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
607   // suffixes).
608   constexpr const char* test_string = "-2147483646";
609   constexpr int64_t test_values[] = {
610                 6,
611                46,
612               646,
613              3646,
614             83646,
615            483646,
616           7483646,
617          47483646,
618         147483646,
619        2147483646,
620       -2147483646
621   };
622 
623   static_assert(arraysize(test_values) == 11U, "test_values");
624   CHECK_EQ(strlen(test_string), 11U);
625 
626   for (size_t i = 0; i <= 10; ++i) {
627     const char* test_value = &test_string[10 - i];
628 
629     StackHandleScope<1> hs_str(self);
630     Handle<mirror::String> h_str(
631         hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
632     ASSERT_NE(h_str.Get(), nullptr);
633     ASSERT_FALSE(self->IsExceptionPending());
634 
635     tmp->SetVRegReference(0, h_str.Get());
636 
637     JValue result;
638     UnstartedLongParseLong(self, tmp, &result, 0);
639 
640     ASSERT_FALSE(self->IsExceptionPending());
641     EXPECT_EQ(result.GetJ(), test_values[i]);
642   }
643 
644   ShadowFrame::DeleteDeoptimizedFrame(tmp);
645 }
646 
TEST_F(UnstartedRuntimeTest,Ceil)647 TEST_F(UnstartedRuntimeTest, Ceil) {
648   Thread* self = Thread::Current();
649   ScopedObjectAccess soa(self);
650 
651   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
652 
653   constexpr double nan = std::numeric_limits<double>::quiet_NaN();
654   constexpr double inf = std::numeric_limits<double>::infinity();
655   constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
656   constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
657   constexpr double test_pairs[][2] = {
658       { -0.0, -0.0 },
659       {  0.0,  0.0 },
660       { -0.5, -0.0 },
661       { -1.0, -1.0 },
662       {  0.5,  1.0 },
663       {  1.0,  1.0 },
664       {  nan,  nan },
665       {  inf,  inf },
666       { -inf, -inf },
667       {  ld1,  ld1 },
668       {  ld2,  ld2 }
669   };
670 
671   TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));
672 
673   ShadowFrame::DeleteDeoptimizedFrame(tmp);
674 }
675 
TEST_F(UnstartedRuntimeTest,Floor)676 TEST_F(UnstartedRuntimeTest, Floor) {
677   Thread* self = Thread::Current();
678   ScopedObjectAccess soa(self);
679 
680   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
681 
682   constexpr double nan = std::numeric_limits<double>::quiet_NaN();
683   constexpr double inf = std::numeric_limits<double>::infinity();
684   constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
685   constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
686   constexpr double test_pairs[][2] = {
687       { -0.0, -0.0 },
688       {  0.0,  0.0 },
689       { -0.5, -1.0 },
690       { -1.0, -1.0 },
691       {  0.5,  0.0 },
692       {  1.0,  1.0 },
693       {  nan,  nan },
694       {  inf,  inf },
695       { -inf, -inf },
696       {  ld1,  ld1 },
697       {  ld2,  ld2 }
698   };
699 
700   TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));
701 
702   ShadowFrame::DeleteDeoptimizedFrame(tmp);
703 }
704 
TEST_F(UnstartedRuntimeTest,ToLowerUpper)705 TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
706   Thread* self = Thread::Current();
707   ScopedObjectAccess soa(self);
708 
709   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
710 
711   std::locale c_locale("C");
712 
713   // Check ASCII.
714   for (uint32_t i = 0; i < 128; ++i) {
715     bool c_upper = std::isupper(static_cast<char>(i), c_locale);
716     bool c_lower = std::islower(static_cast<char>(i), c_locale);
717     EXPECT_FALSE(c_upper && c_lower) << i;
718 
719     // Check toLowerCase.
720     {
721       JValue result;
722       tmp->SetVReg(0, static_cast<int32_t>(i));
723       UnstartedCharacterToLowerCase(self, tmp, &result, 0);
724       ASSERT_FALSE(self->IsExceptionPending());
725       uint32_t lower_result = static_cast<uint32_t>(result.GetI());
726       if (c_lower) {
727         EXPECT_EQ(i, lower_result);
728       } else if (c_upper) {
729         EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
730                   lower_result);
731       } else {
732         EXPECT_EQ(i, lower_result);
733       }
734     }
735 
736     // Check toUpperCase.
737     {
738       JValue result2;
739       tmp->SetVReg(0, static_cast<int32_t>(i));
740       UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
741       ASSERT_FALSE(self->IsExceptionPending());
742       uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
743       if (c_upper) {
744         EXPECT_EQ(i, upper_result);
745       } else if (c_lower) {
746         EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
747                   upper_result);
748       } else {
749         EXPECT_EQ(i, upper_result);
750       }
751     }
752   }
753 
754   // Check abort for other things. Can't test all.
755 
756   PrepareForAborts();
757 
758   for (uint32_t i = 128; i < 256; ++i) {
759     {
760       JValue result;
761       tmp->SetVReg(0, static_cast<int32_t>(i));
762       Transaction transaction;
763       Runtime::Current()->EnterTransactionMode(&transaction);
764       UnstartedCharacterToLowerCase(self, tmp, &result, 0);
765       Runtime::Current()->ExitTransactionMode();
766       ASSERT_TRUE(self->IsExceptionPending());
767       ASSERT_TRUE(transaction.IsAborted());
768     }
769     {
770       JValue result;
771       tmp->SetVReg(0, static_cast<int32_t>(i));
772       Transaction transaction;
773       Runtime::Current()->EnterTransactionMode(&transaction);
774       UnstartedCharacterToUpperCase(self, tmp, &result, 0);
775       Runtime::Current()->ExitTransactionMode();
776       ASSERT_TRUE(self->IsExceptionPending());
777       ASSERT_TRUE(transaction.IsAborted());
778     }
779   }
780   for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
781     {
782       JValue result;
783       tmp->SetVReg(0, static_cast<int32_t>(i));
784       Transaction transaction;
785       Runtime::Current()->EnterTransactionMode(&transaction);
786       UnstartedCharacterToLowerCase(self, tmp, &result, 0);
787       Runtime::Current()->ExitTransactionMode();
788       ASSERT_TRUE(self->IsExceptionPending());
789       ASSERT_TRUE(transaction.IsAborted());
790     }
791     {
792       JValue result;
793       tmp->SetVReg(0, static_cast<int32_t>(i));
794       Transaction transaction;
795       Runtime::Current()->EnterTransactionMode(&transaction);
796       UnstartedCharacterToUpperCase(self, tmp, &result, 0);
797       Runtime::Current()->ExitTransactionMode();
798       ASSERT_TRUE(self->IsExceptionPending());
799       ASSERT_TRUE(transaction.IsAborted());
800     }
801   }
802 
803   ShadowFrame::DeleteDeoptimizedFrame(tmp);
804 }
805 
TEST_F(UnstartedRuntimeTest,Sin)806 TEST_F(UnstartedRuntimeTest, Sin) {
807   Thread* self = Thread::Current();
808   ScopedObjectAccess soa(self);
809 
810   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
811 
812   // Test an important value, PI/6. That's the one we see in practice.
813   constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
814   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
815 
816   JValue result;
817   UnstartedMathSin(self, tmp, &result, 0);
818 
819   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
820   EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
821 
822   ShadowFrame::DeleteDeoptimizedFrame(tmp);
823 }
824 
TEST_F(UnstartedRuntimeTest,Cos)825 TEST_F(UnstartedRuntimeTest, Cos) {
826   Thread* self = Thread::Current();
827   ScopedObjectAccess soa(self);
828 
829   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
830 
831   // Test an important value, PI/6. That's the one we see in practice.
832   constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
833   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
834 
835   JValue result;
836   UnstartedMathCos(self, tmp, &result, 0);
837 
838   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
839   EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
840 
841   ShadowFrame::DeleteDeoptimizedFrame(tmp);
842 }
843 
TEST_F(UnstartedRuntimeTest,Pow)844 TEST_F(UnstartedRuntimeTest, Pow) {
845   // Valgrind seems to get this wrong, actually. Disable for valgrind.
846   if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
847     return;
848   }
849 
850   Thread* self = Thread::Current();
851   ScopedObjectAccess soa(self);
852 
853   ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
854 
855   // Test an important pair.
856   constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
857   constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
858 
859   tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
860   tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
861 
862   JValue result;
863   UnstartedMathPow(self, tmp, &result, 0);
864 
865   const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
866   EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
867 
868   ShadowFrame::DeleteDeoptimizedFrame(tmp);
869 }
870 
871 }  // namespace interpreter
872 }  // namespace art
873