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