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