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_instruction.h"
28 #include "handle.h"
29 #include "handle_scope-inl.h"
30 #include "interpreter/interpreter_common.h"
31 #include "mirror/class_loader.h"
32 #include "mirror/object_array-inl.h"
33 #include "mirror/object-inl.h"
34 #include "mirror/string-inl.h"
35 #include "runtime.h"
36 #include "scoped_thread_state_change-inl.h"
37 #include "thread.h"
38 #include "transaction.h"
39
40 namespace art {
41 namespace interpreter {
42
43 class 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) \
54 REQUIRES_SHARED(Locks::mutator_lock_) { \
55 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.
64 #define UNSTARTED_JNI(Name, SigIgnored) \
65 static void UnstartedJNI ## Name(Thread* self, \
66 ArtMethod* method, \
67 mirror::Object* receiver, \
68 uint32_t* args, \
69 JValue* result) \
70 REQUIRES_SHARED(Locks::mutator_lock_) { \
71 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
72 }
73 #include "unstarted_runtime_list.h"
UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)74 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
75 #undef UNSTARTED_RUNTIME_DIRECT_LIST
76 #undef UNSTARTED_RUNTIME_JNI_LIST
77 #undef UNSTARTED_JNI
78
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,
86 ObjPtr<mirror::Class> component_type,
87 const StackHandleScope<3>& data)
88 REQUIRES_SHARED(Locks::mutator_lock_) {
89 Runtime* runtime = Runtime::Current();
90 ObjPtr<mirror::Class> array_type =
91 runtime->GetClassLinker()->FindArrayClass(self, &component_type);
92 CHECK(array_type != nullptr);
93 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
94 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 }
100 return result.Ptr();
101 }
102
CheckObjectArray(mirror::ObjectArray<mirror::Object> * array,const StackHandleScope<3> & data)103 static void CheckObjectArray(mirror::ObjectArray<mirror::Object>* array,
104 const StackHandleScope<3>& data)
105 REQUIRES_SHARED(Locks::mutator_lock_) {
106 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
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)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)
121 REQUIRES_SHARED(Locks::mutator_lock_) {
122 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
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)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)
147 REQUIRES_SHARED(Locks::mutator_lock_) {
148 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 }
167
TestCeilFloor(bool ceil,Thread * self,ShadowFrame * tmp,double const test_pairs[][2],size_t num_pairs)168 void TestCeilFloor(bool ceil,
169 Thread* self,
170 ShadowFrame* tmp,
171 double const test_pairs[][2],
172 size_t num_pairs)
173 REQUIRES_SHARED(Locks::mutator_lock_) {
174 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 }
192
193 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
194 // loading code doesn't work under transactions.
PrepareForAborts()195 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
196 mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass(
197 Thread::Current(),
198 Transaction::kAbortExceptionSignature,
199 ScopedNullHandle<mirror::ClassLoader>());
200 CHECK(result != nullptr);
201 }
202 };
203
TEST_F(UnstartedRuntimeTest,MemoryPeekByte)204 TEST_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
TEST_F(UnstartedRuntimeTest,MemoryPeekShort)226 TEST_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
TEST_F(UnstartedRuntimeTest,MemoryPeekInt)251 TEST_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
TEST_F(UnstartedRuntimeTest,MemoryPeekLong)276 TEST_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
TEST_F(UnstartedRuntimeTest,StringGetCharsNoCheck)301 TEST_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
TEST_F(UnstartedRuntimeTest,StringCharAt)361 TEST_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
TEST_F(UnstartedRuntimeTest,StringInit)385 TEST_F(UnstartedRuntimeTest, StringInit) {
386 Thread* self = Thread::Current();
387 ScopedObjectAccess soa(self);
388 mirror::Class* klass = mirror::String::GetJavaLangString();
389 ArtMethod* method = klass->FindDeclaredDirectMethod("<init>", "(Ljava/lang/String;)V",
390 kRuntimePointerSize);
391
392 // create instruction data for invoke-direct {v0, v1} of method with fake index
393 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
394 const Instruction* inst = Instruction::At(inst_data);
395
396 JValue result;
397 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
398 const char* base_string = "hello_world";
399 mirror::String* string_arg = mirror::String::AllocFromModifiedUtf8(self, base_string);
400 mirror::String* reference_empty_string = mirror::String::AllocFromModifiedUtf8(self, "");
401 shadow_frame->SetVRegReference(0, reference_empty_string);
402 shadow_frame->SetVRegReference(1, string_arg);
403
404 interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
405 mirror::String* string_result = reinterpret_cast<mirror::String*>(result.GetL());
406 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
407
408 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
409 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
410 string_arg->GetLength() * sizeof(uint8_t)), 0);
411 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
412 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
413 string_arg->GetLength() * sizeof(uint16_t)), 0);
414 } else {
415 bool equal = true;
416 for (int i = 0; i < string_arg->GetLength(); ++i) {
417 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
418 equal = false;
419 break;
420 }
421 }
422 EXPECT_EQ(equal, true);
423 }
424
425 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
426 }
427
428 // Tests the exceptions that should be checked before modifying the destination.
429 // (Doesn't check the object vs primitive case ATM.)
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTestExceptions)430 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
431 Thread* self = Thread::Current();
432 ScopedObjectAccess soa(self);
433 JValue result;
434 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
435
436 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
437 // allocate.
438 StackHandleScope<2> hs_misc(self);
439 Handle<mirror::Class> object_class(
440 hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
441
442 StackHandleScope<3> hs_data(self);
443 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
444 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
445 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
446
447 Handle<mirror::ObjectArray<mirror::Object>> array(
448 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
449
450 RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
451 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
452 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
453 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
454 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
455 RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
456
457 mirror::ObjectArray<mirror::Object>* class_as_array =
458 reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get());
459 RunArrayCopy(self, tmp, true, class_as_array, 0, array.Get(), 0, 0);
460 RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array, 0, 0);
461
462 ShadowFrame::DeleteDeoptimizedFrame(tmp);
463 }
464
TEST_F(UnstartedRuntimeTest,SystemArrayCopyObjectArrayTest)465 TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
466 Thread* self = Thread::Current();
467 ScopedObjectAccess soa(self);
468 JValue result;
469 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
470
471 StackHandleScope<1> hs_object(self);
472 Handle<mirror::Class> object_class(
473 hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
474
475 // Simple test:
476 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
477 {
478 StackHandleScope<3> hs_src(self);
479 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
480 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
481 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
482
483 StackHandleScope<3> hs_dst(self);
484 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
485 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
486 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
487
488 StackHandleScope<3> hs_expected(self);
489 hs_expected.NewHandle(hs_dst.GetReference(0));
490 hs_expected.NewHandle(hs_dst.GetReference(1));
491 hs_expected.NewHandle(hs_src.GetReference(1));
492
493 RunArrayCopy(self,
494 tmp,
495 false,
496 object_class.Get(),
497 object_class.Get(),
498 hs_src,
499 1,
500 hs_dst,
501 2,
502 1,
503 hs_expected);
504 }
505
506 // Simple test:
507 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
508 {
509 StackHandleScope<3> hs_src(self);
510 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
511 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
512 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
513
514 StackHandleScope<3> hs_dst(self);
515 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
516 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
517 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
518
519 StackHandleScope<3> hs_expected(self);
520 hs_expected.NewHandle(hs_dst.GetReference(0));
521 hs_expected.NewHandle(hs_src.GetReference(1));
522 hs_expected.NewHandle(hs_dst.GetReference(2));
523
524 RunArrayCopy(self,
525 tmp,
526 false,
527 object_class.Get(),
528 mirror::String::GetJavaLangString(),
529 hs_src,
530 1,
531 hs_dst,
532 1,
533 1,
534 hs_expected);
535 }
536
537 // Simple test:
538 // [1,*,3] into [4,5,6] = [1,5,6] + exc
539 {
540 StackHandleScope<3> hs_src(self);
541 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
542 hs_src.NewHandle(mirror::String::GetJavaLangString());
543 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
544
545 StackHandleScope<3> hs_dst(self);
546 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
547 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
548 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
549
550 StackHandleScope<3> hs_expected(self);
551 hs_expected.NewHandle(hs_src.GetReference(0));
552 hs_expected.NewHandle(hs_dst.GetReference(1));
553 hs_expected.NewHandle(hs_dst.GetReference(2));
554
555 RunArrayCopy(self,
556 tmp,
557 true,
558 object_class.Get(),
559 mirror::String::GetJavaLangString(),
560 hs_src,
561 0,
562 hs_dst,
563 0,
564 3,
565 hs_expected);
566 }
567
568 ShadowFrame::DeleteDeoptimizedFrame(tmp);
569 }
570
TEST_F(UnstartedRuntimeTest,IntegerParseIntTest)571 TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
572 Thread* self = Thread::Current();
573 ScopedObjectAccess soa(self);
574
575 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
576
577 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
578 // suffixes).
579 constexpr const char* test_string = "-2147483646";
580 constexpr int32_t test_values[] = {
581 6,
582 46,
583 646,
584 3646,
585 83646,
586 483646,
587 7483646,
588 47483646,
589 147483646,
590 2147483646,
591 -2147483646
592 };
593
594 static_assert(arraysize(test_values) == 11U, "test_values");
595 CHECK_EQ(strlen(test_string), 11U);
596
597 for (size_t i = 0; i <= 10; ++i) {
598 const char* test_value = &test_string[10 - i];
599
600 StackHandleScope<1> hs_str(self);
601 Handle<mirror::String> h_str(
602 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
603 ASSERT_NE(h_str.Get(), nullptr);
604 ASSERT_FALSE(self->IsExceptionPending());
605
606 tmp->SetVRegReference(0, h_str.Get());
607
608 JValue result;
609 UnstartedIntegerParseInt(self, tmp, &result, 0);
610
611 ASSERT_FALSE(self->IsExceptionPending());
612 EXPECT_EQ(result.GetI(), test_values[i]);
613 }
614
615 ShadowFrame::DeleteDeoptimizedFrame(tmp);
616 }
617
618 // Right now the same as Integer.Parse
TEST_F(UnstartedRuntimeTest,LongParseLongTest)619 TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
620 Thread* self = Thread::Current();
621 ScopedObjectAccess soa(self);
622
623 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
624
625 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
626 // suffixes).
627 constexpr const char* test_string = "-2147483646";
628 constexpr int64_t test_values[] = {
629 6,
630 46,
631 646,
632 3646,
633 83646,
634 483646,
635 7483646,
636 47483646,
637 147483646,
638 2147483646,
639 -2147483646
640 };
641
642 static_assert(arraysize(test_values) == 11U, "test_values");
643 CHECK_EQ(strlen(test_string), 11U);
644
645 for (size_t i = 0; i <= 10; ++i) {
646 const char* test_value = &test_string[10 - i];
647
648 StackHandleScope<1> hs_str(self);
649 Handle<mirror::String> h_str(
650 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
651 ASSERT_NE(h_str.Get(), nullptr);
652 ASSERT_FALSE(self->IsExceptionPending());
653
654 tmp->SetVRegReference(0, h_str.Get());
655
656 JValue result;
657 UnstartedLongParseLong(self, tmp, &result, 0);
658
659 ASSERT_FALSE(self->IsExceptionPending());
660 EXPECT_EQ(result.GetJ(), test_values[i]);
661 }
662
663 ShadowFrame::DeleteDeoptimizedFrame(tmp);
664 }
665
TEST_F(UnstartedRuntimeTest,Ceil)666 TEST_F(UnstartedRuntimeTest, Ceil) {
667 Thread* self = Thread::Current();
668 ScopedObjectAccess soa(self);
669
670 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
671
672 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
673 constexpr double inf = std::numeric_limits<double>::infinity();
674 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
675 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
676 constexpr double test_pairs[][2] = {
677 { -0.0, -0.0 },
678 { 0.0, 0.0 },
679 { -0.5, -0.0 },
680 { -1.0, -1.0 },
681 { 0.5, 1.0 },
682 { 1.0, 1.0 },
683 { nan, nan },
684 { inf, inf },
685 { -inf, -inf },
686 { ld1, ld1 },
687 { ld2, ld2 }
688 };
689
690 TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));
691
692 ShadowFrame::DeleteDeoptimizedFrame(tmp);
693 }
694
TEST_F(UnstartedRuntimeTest,Floor)695 TEST_F(UnstartedRuntimeTest, Floor) {
696 Thread* self = Thread::Current();
697 ScopedObjectAccess soa(self);
698
699 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
700
701 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
702 constexpr double inf = std::numeric_limits<double>::infinity();
703 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
704 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
705 constexpr double test_pairs[][2] = {
706 { -0.0, -0.0 },
707 { 0.0, 0.0 },
708 { -0.5, -1.0 },
709 { -1.0, -1.0 },
710 { 0.5, 0.0 },
711 { 1.0, 1.0 },
712 { nan, nan },
713 { inf, inf },
714 { -inf, -inf },
715 { ld1, ld1 },
716 { ld2, ld2 }
717 };
718
719 TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));
720
721 ShadowFrame::DeleteDeoptimizedFrame(tmp);
722 }
723
TEST_F(UnstartedRuntimeTest,ToLowerUpper)724 TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
725 Thread* self = Thread::Current();
726 ScopedObjectAccess soa(self);
727
728 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
729
730 std::locale c_locale("C");
731
732 // Check ASCII.
733 for (uint32_t i = 0; i < 128; ++i) {
734 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
735 bool c_lower = std::islower(static_cast<char>(i), c_locale);
736 EXPECT_FALSE(c_upper && c_lower) << i;
737
738 // Check toLowerCase.
739 {
740 JValue result;
741 tmp->SetVReg(0, static_cast<int32_t>(i));
742 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
743 ASSERT_FALSE(self->IsExceptionPending());
744 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
745 if (c_lower) {
746 EXPECT_EQ(i, lower_result);
747 } else if (c_upper) {
748 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
749 lower_result);
750 } else {
751 EXPECT_EQ(i, lower_result);
752 }
753 }
754
755 // Check toUpperCase.
756 {
757 JValue result2;
758 tmp->SetVReg(0, static_cast<int32_t>(i));
759 UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
760 ASSERT_FALSE(self->IsExceptionPending());
761 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
762 if (c_upper) {
763 EXPECT_EQ(i, upper_result);
764 } else if (c_lower) {
765 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
766 upper_result);
767 } else {
768 EXPECT_EQ(i, upper_result);
769 }
770 }
771 }
772
773 // Check abort for other things. Can't test all.
774
775 PrepareForAborts();
776
777 for (uint32_t i = 128; i < 256; ++i) {
778 {
779 JValue result;
780 tmp->SetVReg(0, static_cast<int32_t>(i));
781 Transaction transaction;
782 Runtime::Current()->EnterTransactionMode(&transaction);
783 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
784 Runtime::Current()->ExitTransactionMode();
785 ASSERT_TRUE(self->IsExceptionPending());
786 ASSERT_TRUE(transaction.IsAborted());
787 }
788 {
789 JValue result;
790 tmp->SetVReg(0, static_cast<int32_t>(i));
791 Transaction transaction;
792 Runtime::Current()->EnterTransactionMode(&transaction);
793 UnstartedCharacterToUpperCase(self, tmp, &result, 0);
794 Runtime::Current()->ExitTransactionMode();
795 ASSERT_TRUE(self->IsExceptionPending());
796 ASSERT_TRUE(transaction.IsAborted());
797 }
798 }
799 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
800 {
801 JValue result;
802 tmp->SetVReg(0, static_cast<int32_t>(i));
803 Transaction transaction;
804 Runtime::Current()->EnterTransactionMode(&transaction);
805 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
806 Runtime::Current()->ExitTransactionMode();
807 ASSERT_TRUE(self->IsExceptionPending());
808 ASSERT_TRUE(transaction.IsAborted());
809 }
810 {
811 JValue result;
812 tmp->SetVReg(0, static_cast<int32_t>(i));
813 Transaction transaction;
814 Runtime::Current()->EnterTransactionMode(&transaction);
815 UnstartedCharacterToUpperCase(self, tmp, &result, 0);
816 Runtime::Current()->ExitTransactionMode();
817 ASSERT_TRUE(self->IsExceptionPending());
818 ASSERT_TRUE(transaction.IsAborted());
819 }
820 }
821
822 ShadowFrame::DeleteDeoptimizedFrame(tmp);
823 }
824
TEST_F(UnstartedRuntimeTest,Sin)825 TEST_F(UnstartedRuntimeTest, Sin) {
826 Thread* self = Thread::Current();
827 ScopedObjectAccess soa(self);
828
829 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
830
831 // Test an important value, PI/6. That's the one we see in practice.
832 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
833 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
834
835 JValue result;
836 UnstartedMathSin(self, tmp, &result, 0);
837
838 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
839 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
840
841 ShadowFrame::DeleteDeoptimizedFrame(tmp);
842 }
843
TEST_F(UnstartedRuntimeTest,Cos)844 TEST_F(UnstartedRuntimeTest, Cos) {
845 Thread* self = Thread::Current();
846 ScopedObjectAccess soa(self);
847
848 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
849
850 // Test an important value, PI/6. That's the one we see in practice.
851 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
852 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
853
854 JValue result;
855 UnstartedMathCos(self, tmp, &result, 0);
856
857 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
858 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
859
860 ShadowFrame::DeleteDeoptimizedFrame(tmp);
861 }
862
TEST_F(UnstartedRuntimeTest,Pow)863 TEST_F(UnstartedRuntimeTest, Pow) {
864 // Valgrind seems to get this wrong, actually. Disable for valgrind.
865 if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
866 return;
867 }
868
869 Thread* self = Thread::Current();
870 ScopedObjectAccess soa(self);
871
872 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
873
874 // Test an important pair.
875 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
876 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
877
878 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
879 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
880
881 JValue result;
882 UnstartedMathPow(self, tmp, &result, 0);
883
884 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
885 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
886
887 ShadowFrame::DeleteDeoptimizedFrame(tmp);
888 }
889
TEST_F(UnstartedRuntimeTest,IsAnonymousClass)890 TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
891 Thread* self = Thread::Current();
892 ScopedObjectAccess soa(self);
893
894 JValue result;
895 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
896
897 mirror::Class* class_klass = mirror::Class::GetJavaLangClass();
898 shadow_frame->SetVRegReference(0, class_klass);
899 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
900 EXPECT_EQ(result.GetZ(), 0);
901
902 jobject class_loader = LoadDex("Nested");
903 StackHandleScope<1> hs(soa.Self());
904 Handle<mirror::ClassLoader> loader(
905 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
906 mirror::Class* c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
907 ASSERT_TRUE(c != nullptr);
908 shadow_frame->SetVRegReference(0, c);
909 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
910 EXPECT_EQ(result.GetZ(), 1);
911
912 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
913 }
914
TEST_F(UnstartedRuntimeTest,GetDeclaringClass)915 TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
916 Thread* self = Thread::Current();
917 ScopedObjectAccess soa(self);
918
919 JValue result;
920 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
921
922 jobject class_loader = LoadDex("Nested");
923 StackHandleScope<4> hs(self);
924 Handle<mirror::ClassLoader> loader(
925 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
926
927 Handle<mirror::Class> nested_klass(hs.NewHandle(
928 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
929 Handle<mirror::Class> inner_klass(hs.NewHandle(
930 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
931 Handle<mirror::Class> anon_klass(hs.NewHandle(
932 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
933
934 shadow_frame->SetVRegReference(0, nested_klass.Get());
935 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
936 EXPECT_EQ(result.GetL(), nullptr);
937
938 shadow_frame->SetVRegReference(0, inner_klass.Get());
939 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
940 EXPECT_EQ(result.GetL(), nested_klass.Get());
941
942 shadow_frame->SetVRegReference(0, anon_klass.Get());
943 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
944 EXPECT_EQ(result.GetL(), nullptr);
945
946 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
947 }
948
TEST_F(UnstartedRuntimeTest,ThreadLocalGet)949 TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
950 Thread* self = Thread::Current();
951 ScopedObjectAccess soa(self);
952
953 JValue result;
954 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
955
956 StackHandleScope<1> hs(self);
957 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
958
959 // Positive test. See that We get something for float conversion.
960 {
961 Handle<mirror::Class> floating_decimal = hs.NewHandle(
962 class_linker->FindClass(self,
963 "Lsun/misc/FloatingDecimal;",
964 ScopedNullHandle<mirror::ClassLoader>()));
965 ASSERT_TRUE(floating_decimal != nullptr);
966 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
967
968 ArtMethod* caller_method = floating_decimal->FindDeclaredDirectMethod(
969 "getBinaryToASCIIBuffer",
970 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
971 class_linker->GetImagePointerSize());
972 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
973 ASSERT_TRUE(caller_method != nullptr);
974 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
975 shadow_frame->SetLink(caller_frame);
976
977 UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
978 EXPECT_TRUE(result.GetL() != nullptr);
979 EXPECT_FALSE(self->IsExceptionPending());
980
981 ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
982 }
983
984 // Negative test.
985 PrepareForAborts();
986
987 {
988 // Just use a method in Class.
989 ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
990 ArtMethod* caller_method =
991 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
992 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
993 shadow_frame->SetLink(caller_frame);
994
995 Transaction transaction;
996 Runtime::Current()->EnterTransactionMode(&transaction);
997 UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
998 Runtime::Current()->ExitTransactionMode();
999 ASSERT_TRUE(self->IsExceptionPending());
1000 ASSERT_TRUE(transaction.IsAborted());
1001 self->ClearException();
1002
1003 ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
1004 }
1005
1006 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1007 }
1008
TEST_F(UnstartedRuntimeTest,FloatConversion)1009 TEST_F(UnstartedRuntimeTest, FloatConversion) {
1010 Thread* self = Thread::Current();
1011 ScopedObjectAccess soa(self);
1012
1013 StackHandleScope<1> hs(self);
1014 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1015 Handle<mirror::Class> double_class = hs.NewHandle(
1016 class_linker->FindClass(self,
1017 "Ljava/lang/Double;",
1018 ScopedNullHandle<mirror::ClassLoader>()));
1019 ASSERT_TRUE(double_class != nullptr);
1020 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1021
1022 ArtMethod* method = double_class->FindDeclaredDirectMethod("toString",
1023 "(D)Ljava/lang/String;",
1024 class_linker->GetImagePointerSize());
1025 ASSERT_TRUE(method != nullptr);
1026
1027 // create instruction data for invoke-direct {v0, v1} of method with fake index
1028 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
1029 const Instruction* inst = Instruction::At(inst_data);
1030
1031 JValue result;
1032 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
1033 shadow_frame->SetVRegDouble(0, 1.23);
1034 interpreter::DoCall<false, false>(method, self, *shadow_frame, inst, inst_data[0], &result);
1035 ObjPtr<mirror::String> string_result = reinterpret_cast<mirror::String*>(result.GetL());
1036 ASSERT_TRUE(string_result != nullptr);
1037
1038 std::string mod_utf = string_result->ToModifiedUtf8();
1039 EXPECT_EQ("1.23", mod_utf);
1040
1041 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1042 }
1043
TEST_F(UnstartedRuntimeTest,ThreadCurrentThread)1044 TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1045 Thread* self = Thread::Current();
1046 ScopedObjectAccess soa(self);
1047
1048 JValue result;
1049 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1050
1051 StackHandleScope<1> hs(self);
1052 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1053 Handle<mirror::Class> thread_class = hs.NewHandle(
1054 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1055 ASSERT_TRUE(thread_class.Get() != nullptr);
1056 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1057
1058 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1059 // be recreated at runtime).
1060 PrepareForAborts();
1061
1062 {
1063 Transaction transaction;
1064 Runtime::Current()->EnterTransactionMode(&transaction);
1065 UnstartedThreadCurrentThread(self, shadow_frame, &result, 0);
1066 Runtime::Current()->ExitTransactionMode();
1067 ASSERT_TRUE(self->IsExceptionPending());
1068 ASSERT_TRUE(transaction.IsAborted());
1069 self->ClearException();
1070 }
1071
1072 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1073 }
1074
TEST_F(UnstartedRuntimeTest,LogManager)1075 TEST_F(UnstartedRuntimeTest, LogManager) {
1076 Thread* self = Thread::Current();
1077 ScopedObjectAccess soa(self);
1078
1079 StackHandleScope<1> hs(self);
1080 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1081 Handle<mirror::Class> log_manager_class = hs.NewHandle(
1082 class_linker->FindClass(self,
1083 "Ljava/util/logging/LogManager;",
1084 ScopedNullHandle<mirror::ClassLoader>()));
1085 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1086 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1087 }
1088
1089 class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1090 public:
1091 template <typename T>
RunTest(T & runner,bool in_transaction,bool should_succeed)1092 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1093 Thread* self = Thread::Current();
1094 ScopedObjectAccess soa(self);
1095
1096 // Ensure that Class is initialized.
1097 {
1098 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1099 StackHandleScope<1> hs(self);
1100 Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass());
1101 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1102 }
1103
1104 // A selection of classes from different core classpath components.
1105 constexpr const char* kTestCases[] = {
1106 "java.net.CookieManager", // From libcore.
1107 "dalvik.system.ClassExt", // From libart.
1108 };
1109
1110 if (in_transaction) {
1111 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1112 // classes isn't transactional. Load them ahead of time.
1113 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1114 for (const char* name : kTestCases) {
1115 class_linker->FindClass(self,
1116 DotToDescriptor(name).c_str(),
1117 ScopedNullHandle<mirror::ClassLoader>());
1118 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1119 }
1120 }
1121
1122 if (!should_succeed) {
1123 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1124 // be recreated at runtime).
1125 PrepareForAborts();
1126 }
1127
1128 JValue result;
1129 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1130
1131 for (const char* name : kTestCases) {
1132 mirror::String* name_string = mirror::String::AllocFromModifiedUtf8(self, name);
1133 CHECK(name_string != nullptr);
1134
1135 Transaction transaction;
1136 if (in_transaction) {
1137 Runtime::Current()->EnterTransactionMode(&transaction);
1138 }
1139 CHECK(!self->IsExceptionPending());
1140
1141 runner(self, shadow_frame, name_string, &result);
1142
1143 if (in_transaction) {
1144 Runtime::Current()->ExitTransactionMode();
1145 }
1146
1147 if (should_succeed) {
1148 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1149 CHECK(result.GetL() != nullptr) << name;
1150 } else {
1151 CHECK(self->IsExceptionPending()) << name;
1152 if (in_transaction) {
1153 ASSERT_TRUE(transaction.IsAborted());
1154 }
1155 self->ClearException();
1156 }
1157 }
1158
1159 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1160 }
1161
GetBootClassLoader()1162 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1163 Thread* self = Thread::Current();
1164 StackHandleScope<2> hs(self);
1165 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1166
1167 {
1168 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1169
1170 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1171 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1172 class_linker->FindClass(self,
1173 "Ljava/lang/BootClassLoader;",
1174 ScopedNullHandle<mirror::ClassLoader>()));
1175 CHECK(boot_cp_class != nullptr);
1176 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1177
1178 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1179 CHECK(boot_cp != nullptr);
1180
1181 ArtMethod* boot_cp_init = boot_cp_class->FindDeclaredDirectMethod(
1182 "<init>", "()V", class_linker->GetImagePointerSize());
1183 CHECK(boot_cp_init != nullptr);
1184
1185 JValue result;
1186 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0);
1187 shadow_frame->SetVRegReference(0, boot_cp.Get());
1188
1189 // create instruction data for invoke-direct {v0} of method with fake index
1190 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
1191 const Instruction* inst = Instruction::At(inst_data);
1192
1193 interpreter::DoCall<false, false>(boot_cp_init,
1194 self,
1195 *shadow_frame,
1196 inst,
1197 inst_data[0],
1198 &result);
1199 CHECK(!self->IsExceptionPending());
1200
1201 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1202 }
1203
1204 return boot_cp.Get();
1205 }
1206 };
1207
TEST_F(UnstartedClassForNameTest,ClassForName)1208 TEST_F(UnstartedClassForNameTest, ClassForName) {
1209 auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
1210 REQUIRES_SHARED(Locks::mutator_lock_) {
1211 shadow_frame->SetVRegReference(0, name);
1212 UnstartedClassForName(self, shadow_frame, result, 0);
1213 };
1214 RunTest(runner, false, true);
1215 }
1216
TEST_F(UnstartedClassForNameTest,ClassForNameLong)1217 TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
1218 auto runner = [](Thread* self, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
1219 REQUIRES_SHARED(Locks::mutator_lock_) {
1220 shadow_frame->SetVRegReference(0, name);
1221 shadow_frame->SetVReg(1, 0);
1222 shadow_frame->SetVRegReference(2, nullptr);
1223 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1224 };
1225 RunTest(runner, false, true);
1226 }
1227
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoader)1228 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1229 Thread* self = Thread::Current();
1230 ScopedObjectAccess soa(self);
1231
1232 StackHandleScope<1> hs(self);
1233 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1234
1235 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
1236 REQUIRES_SHARED(Locks::mutator_lock_) {
1237 shadow_frame->SetVRegReference(0, name);
1238 shadow_frame->SetVReg(1, 0);
1239 shadow_frame->SetVRegReference(2, boot_cp.Get());
1240 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1241 };
1242 RunTest(runner, false, true);
1243 }
1244
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoaderTransaction)1245 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1246 Thread* self = Thread::Current();
1247 ScopedObjectAccess soa(self);
1248
1249 StackHandleScope<1> hs(self);
1250 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1251
1252 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
1253 REQUIRES_SHARED(Locks::mutator_lock_) {
1254 shadow_frame->SetVRegReference(0, name);
1255 shadow_frame->SetVReg(1, 0);
1256 shadow_frame->SetVRegReference(2, boot_cp.Get());
1257 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1258 };
1259 RunTest(runner, true, true);
1260 }
1261
TEST_F(UnstartedClassForNameTest,ClassForNameLongWithClassLoaderFail)1262 TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1263 Thread* self = Thread::Current();
1264 ScopedObjectAccess soa(self);
1265
1266 StackHandleScope<2> hs(self);
1267 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1268 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1269 ASSERT_TRUE(path_jobj != nullptr);
1270 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1271 self->DecodeJObject(path_jobj)->AsClassLoader());
1272
1273 auto runner = [&](Thread* th, ShadowFrame* shadow_frame, mirror::String* name, JValue* result)
1274 REQUIRES_SHARED(Locks::mutator_lock_) {
1275 shadow_frame->SetVRegReference(0, name);
1276 shadow_frame->SetVReg(1, 0);
1277 shadow_frame->SetVRegReference(2, path_cp.Get());
1278 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1279 };
1280 RunTest(runner, true, false);
1281 }
1282
TEST_F(UnstartedRuntimeTest,ClassGetSignatureAnnotation)1283 TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1284 Thread* self = Thread::Current();
1285 ScopedObjectAccess soa(self);
1286
1287 StackHandleScope<1> hs(self);
1288 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1289 Handle<mirror::Class> list_class = hs.NewHandle(
1290 class_linker->FindClass(self,
1291 "Ljava/util/List;",
1292 ScopedNullHandle<mirror::ClassLoader>()));
1293 ASSERT_TRUE(list_class.Get() != nullptr);
1294 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1295
1296 JValue result;
1297 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1298
1299 shadow_frame->SetVRegReference(0, list_class.Get());
1300 UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0);
1301 ASSERT_TRUE(result.GetL() != nullptr);
1302 ASSERT_FALSE(self->IsExceptionPending());
1303
1304 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1305
1306 ASSERT_TRUE(result.GetL()->IsObjectArray());
1307 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1308 result.GetL()->AsObjectArray<mirror::Object>();
1309 std::ostringstream oss;
1310 for (int32_t i = 0; i != array->GetLength(); ++i) {
1311 ObjPtr<mirror::Object> elem = array->Get(i);
1312 ASSERT_TRUE(elem != nullptr);
1313 ASSERT_TRUE(elem->IsString());
1314 oss << elem->AsString()->ToModifiedUtf8();
1315 }
1316 std::string output_string = oss.str();
1317 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1318 }
1319
TEST_F(UnstartedRuntimeTest,ConstructorNewInstance0)1320 TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1321 Thread* self = Thread::Current();
1322 ScopedObjectAccess soa(self);
1323
1324 StackHandleScope<4> hs(self);
1325 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1326
1327 // Get Throwable.
1328 Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable());
1329 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1330
1331 // Get an input object.
1332 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1333
1334 // Find the constructor.
1335 ArtMethod* throw_cons = throw_class->FindDeclaredDirectMethod(
1336 "<init>", "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
1337 ASSERT_TRUE(throw_cons != nullptr);
1338
1339 Handle<mirror::Constructor> cons = hs.NewHandle(
1340 mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(self, throw_cons));
1341 ASSERT_TRUE(cons != nullptr);
1342
1343 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
1344 mirror::ObjectArray<mirror::Object>::Alloc(
1345 self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1));
1346 ASSERT_TRUE(args != nullptr);
1347 args->Set(0, input.Get());
1348
1349 // OK, we're ready now.
1350 JValue result;
1351 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1352 shadow_frame->SetVRegReference(0, cons.Get());
1353 shadow_frame->SetVRegReference(1, args.Get());
1354 UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0);
1355
1356 ASSERT_TRUE(result.GetL() != nullptr);
1357 ASSERT_FALSE(self->IsExceptionPending());
1358
1359 // Should be a new object.
1360 ASSERT_NE(result.GetL(), input.Get());
1361 // Should be a String.
1362 ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass());
1363 // Should have the right string.
1364 ObjPtr<mirror::String> result_msg =
1365 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
1366 EXPECT_EQ(input.Get(), result_msg.Ptr());
1367
1368 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1369 }
1370
TEST_F(UnstartedRuntimeTest,IdentityHashCode)1371 TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1372 Thread* self = Thread::Current();
1373 ScopedObjectAccess soa(self);
1374 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1375
1376 JValue result;
1377 UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1378
1379 EXPECT_EQ(0, result.GetI());
1380 ASSERT_FALSE(self->IsExceptionPending());
1381
1382 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
1383 tmp->SetVRegReference(0, str.Ptr());
1384 UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1385 EXPECT_NE(0, result.GetI());
1386 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1387 ASSERT_FALSE(self->IsExceptionPending());
1388
1389 ShadowFrame::DeleteDeoptimizedFrame(tmp);
1390 }
1391
1392 } // namespace interpreter
1393 } // namespace art
1394