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