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