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