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