blob: 449458ce6fb00279b774a0136c51afbe81304bef [file] [log] [blame]
Andreas Gampe799681b2015-05-15 19:24:12 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "unstarted_runtime.h"
18
Andreas Gampe89e3b482016-04-12 18:07:36 -070019#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070020#include <locale>
Andreas Gampe89e3b482016-04-12 18:07:36 -070021
22#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070023#include "base/enums.h"
Andreas Gampeb6795152016-04-21 17:23:31 -070024#include "base/memory_tool.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070025#include "class_linker.h"
Vladimir Markob4eb1b12018-05-24 11:09:38 +010026#include "class_root.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070027#include "common_runtime_test.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080028#include "dex/descriptors_names.h"
David Sehr9e734c72018-01-04 17:56:19 -080029#include "dex/dex_instruction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070030#include "handle.h"
31#include "handle_scope-inl.h"
Jeff Hao400ce002015-05-29 10:53:17 -070032#include "interpreter/interpreter_common.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070033#include "mirror/class_loader.h"
Andreas Gampe9486a162017-02-16 15:17:47 -080034#include "mirror/object-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070035#include "mirror/object_array-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070036#include "mirror/string-inl.h"
37#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070038#include "scoped_thread_state_change-inl.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010039#include "shadow_frame-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070040#include "thread.h"
Andreas Gampe8ce9c302016-04-15 21:24:28 -070041#include "transaction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070042
43namespace art {
44namespace interpreter {
45
46class UnstartedRuntimeTest : public CommonRuntimeTest {
47 protected:
48 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
49 // test friends.
50
51 // Methods that intercept available libcore implementations.
52#define UNSTARTED_DIRECT(Name, SigIgnored) \
53 static void Unstarted ## Name(Thread* self, \
54 ShadowFrame* shadow_frame, \
55 JValue* result, \
56 size_t arg_offset) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070057 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070058 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
59 }
60#include "unstarted_runtime_list.h"
61 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
62#undef UNSTARTED_RUNTIME_DIRECT_LIST
63#undef UNSTARTED_RUNTIME_JNI_LIST
64#undef UNSTARTED_DIRECT
65
66 // Methods that are native.
Mathieu Chartiere401d142015-04-22 13:56:20 -070067#define UNSTARTED_JNI(Name, SigIgnored) \
Andreas Gampe799681b2015-05-15 19:24:12 -070068 static void UnstartedJNI ## Name(Thread* self, \
Mathieu Chartiere401d142015-04-22 13:56:20 -070069 ArtMethod* method, \
Andreas Gampe799681b2015-05-15 19:24:12 -070070 mirror::Object* receiver, \
71 uint32_t* args, \
72 JValue* result) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070073 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070074 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
75 }
76#include "unstarted_runtime_list.h"
77 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
78#undef UNSTARTED_RUNTIME_DIRECT_LIST
79#undef UNSTARTED_RUNTIME_JNI_LIST
80#undef UNSTARTED_JNI
Andreas Gampe85a098a2016-03-31 13:30:53 -070081
82 // Helpers for ArrayCopy.
83 //
84 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
85 // of three everywhere. That is enough to test all cases.
86
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010087 static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
Andreas Gampe85a098a2016-03-31 13:30:53 -070088 Thread* self,
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070089 ObjPtr<mirror::Class> component_type,
Andreas Gampe85a098a2016-03-31 13:30:53 -070090 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070091 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -070092 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070093 ObjPtr<mirror::Class> array_type =
94 runtime->GetClassLinker()->FindArrayClass(self, &component_type);
Andreas Gampe85a098a2016-03-31 13:30:53 -070095 CHECK(array_type != nullptr);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070096 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
Andreas Gampe85a098a2016-03-31 13:30:53 -070097 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
98 CHECK(result != nullptr);
99 for (size_t i = 0; i < 3; ++i) {
100 result->Set(static_cast<int32_t>(i), data.GetReference(i));
101 CHECK(!self->IsExceptionPending());
102 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100103 return result;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700104 }
105
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100106 static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700107 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700108 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700109 CHECK_EQ(array->GetLength(), 3);
110 CHECK_EQ(data.NumberOfReferences(), 3U);
111 for (size_t i = 0; i < 3; ++i) {
112 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
113 }
114 }
115
116 void RunArrayCopy(Thread* self,
117 ShadowFrame* tmp,
118 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100119 ObjPtr<mirror::ObjectArray<mirror::Object>> src,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700120 int32_t src_pos,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100121 ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700122 int32_t dst_pos,
123 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700124 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700125 JValue result;
126 tmp->SetVRegReference(0, src);
127 tmp->SetVReg(1, src_pos);
128 tmp->SetVRegReference(2, dst);
129 tmp->SetVReg(3, dst_pos);
130 tmp->SetVReg(4, length);
131 UnstartedSystemArraycopy(self, tmp, &result, 0);
132 bool exception_pending = self->IsExceptionPending();
133 EXPECT_EQ(exception_pending, expect_exception);
134 if (exception_pending) {
135 self->ClearException();
136 }
137 }
138
139 void RunArrayCopy(Thread* self,
140 ShadowFrame* tmp,
141 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100142 ObjPtr<mirror::Class> src_component_class,
143 ObjPtr<mirror::Class> dst_component_class,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700144 const StackHandleScope<3>& src_data,
145 int32_t src_pos,
146 const StackHandleScope<3>& dst_data,
147 int32_t dst_pos,
148 int32_t length,
149 const StackHandleScope<3>& expected_result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700150 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700151 StackHandleScope<3> hs_misc(self);
152 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
153
154 Handle<mirror::ObjectArray<mirror::Object>> src_handle(
155 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
156
157 Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
158 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
159
160 RunArrayCopy(self,
161 tmp,
162 expect_exception,
163 src_handle.Get(),
164 src_pos,
165 dst_handle.Get(),
166 dst_pos,
167 length);
168 CheckObjectArray(dst_handle.Get(), expected_result);
169 }
Andreas Gampe89e3b482016-04-12 18:07:36 -0700170
171 void TestCeilFloor(bool ceil,
172 Thread* self,
173 ShadowFrame* tmp,
174 double const test_pairs[][2],
175 size_t num_pairs)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700176 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700177 for (size_t i = 0; i < num_pairs; ++i) {
178 tmp->SetVRegDouble(0, test_pairs[i][0]);
179
180 JValue result;
181 if (ceil) {
182 UnstartedMathCeil(self, tmp, &result, 0);
183 } else {
184 UnstartedMathFloor(self, tmp, &result, 0);
185 }
186
187 ASSERT_FALSE(self->IsExceptionPending());
188
189 // We want precise results.
190 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
191 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
192 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
193 }
194 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700195
196 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
197 // loading code doesn't work under transactions.
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700198 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100199 ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700200 Thread::Current(),
201 Transaction::kAbortExceptionSignature,
202 ScopedNullHandle<mirror::ClassLoader>());
203 CHECK(result != nullptr);
204 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700205};
206
207TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
208 Thread* self = Thread::Current();
209
210 ScopedObjectAccess soa(self);
211 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
212 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
213 const uint8_t* base_ptr = base_array;
214
215 JValue result;
216 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
217
218 for (int32_t i = 0; i < kBaseLen; ++i) {
219 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
220
221 UnstartedMemoryPeekByte(self, tmp, &result, 0);
222
223 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
224 }
225
226 ShadowFrame::DeleteDeoptimizedFrame(tmp);
227}
228
229TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
230 Thread* self = Thread::Current();
231
232 ScopedObjectAccess soa(self);
233 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
234 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
235 const uint8_t* base_ptr = base_array;
236
237 JValue result;
238 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
239
240 int32_t adjusted_length = kBaseLen - sizeof(int16_t);
241 for (int32_t i = 0; i < adjusted_length; ++i) {
242 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
243
244 UnstartedMemoryPeekShort(self, tmp, &result, 0);
245
246 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
247 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
248 EXPECT_EQ(result.GetS(), *short_ptr);
249 }
250
251 ShadowFrame::DeleteDeoptimizedFrame(tmp);
252}
253
254TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
255 Thread* self = Thread::Current();
256
257 ScopedObjectAccess soa(self);
258 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
259 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
260 const uint8_t* base_ptr = base_array;
261
262 JValue result;
263 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
264
265 int32_t adjusted_length = kBaseLen - sizeof(int32_t);
266 for (int32_t i = 0; i < adjusted_length; ++i) {
267 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
268
269 UnstartedMemoryPeekInt(self, tmp, &result, 0);
270
271 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
272 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
273 EXPECT_EQ(result.GetI(), *int_ptr);
274 }
275
276 ShadowFrame::DeleteDeoptimizedFrame(tmp);
277}
278
279TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
280 Thread* self = Thread::Current();
281
282 ScopedObjectAccess soa(self);
283 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
284 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
285 const uint8_t* base_ptr = base_array;
286
287 JValue result;
288 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
289
290 int32_t adjusted_length = kBaseLen - sizeof(int64_t);
291 for (int32_t i = 0; i < adjusted_length; ++i) {
292 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
293
294 UnstartedMemoryPeekLong(self, tmp, &result, 0);
295
296 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
297 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
298 EXPECT_EQ(result.GetJ(), *long_ptr);
299 }
300
301 ShadowFrame::DeleteDeoptimizedFrame(tmp);
302}
303
304TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
305 Thread* self = Thread::Current();
306
307 ScopedObjectAccess soa(self);
308 StackHandleScope<2> hs(self);
309 // TODO: Actual UTF.
310 constexpr const char base_string[] = "abcdefghijklmnop";
311 Handle<mirror::String> h_test_string(hs.NewHandle(
312 mirror::String::AllocFromModifiedUtf8(self, base_string)));
313 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
314 Handle<mirror::CharArray> h_char_array(hs.NewHandle(
315 mirror::CharArray::Alloc(self, kBaseLen)));
316 // A buffer so we can make sure we only modify the elements targetted.
317 uint16_t buf[kBaseLen];
318
319 JValue result;
320 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
321
322 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
323 for (int32_t count = 0; count <= kBaseLen; ++count) {
324 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
325 // Only do it when in bounds.
326 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
327 tmp->SetVRegReference(0, h_test_string.Get());
328 tmp->SetVReg(1, start_index);
329 tmp->SetVReg(2, count);
330 tmp->SetVRegReference(3, h_char_array.Get());
331 tmp->SetVReg(3, trg_offset);
332
333 // Copy the char_array into buf.
334 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
335
336 UnstartedStringCharAt(self, tmp, &result, 0);
337
338 uint16_t* data = h_char_array->GetData();
339
340 bool success = true;
341
342 // First segment should be unchanged.
343 for (int32_t i = 0; i < trg_offset; ++i) {
344 success = success && (data[i] == buf[i]);
345 }
346 // Second segment should be a copy.
347 for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
348 success = success && (data[i] == buf[i - trg_offset + start_index]);
349 }
350 // Third segment should be unchanged.
351 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
352 success = success && (data[i] == buf[i]);
353 }
354
355 EXPECT_TRUE(success);
356 }
357 }
358 }
359 }
360
361 ShadowFrame::DeleteDeoptimizedFrame(tmp);
362}
363
364TEST_F(UnstartedRuntimeTest, StringCharAt) {
365 Thread* self = Thread::Current();
366
367 ScopedObjectAccess soa(self);
368 // TODO: Actual UTF.
369 constexpr const char* base_string = "abcdefghijklmnop";
370 int32_t base_len = static_cast<int32_t>(strlen(base_string));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100371 ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
Andreas Gampe799681b2015-05-15 19:24:12 -0700372
373 JValue result;
374 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
375
376 for (int32_t i = 0; i < base_len; ++i) {
377 tmp->SetVRegReference(0, test_string);
378 tmp->SetVReg(1, i);
379
380 UnstartedStringCharAt(self, tmp, &result, 0);
381
382 EXPECT_EQ(result.GetI(), base_string[i]);
383 }
384
385 ShadowFrame::DeleteDeoptimizedFrame(tmp);
386}
387
Jeff Hao400ce002015-05-29 10:53:17 -0700388TEST_F(UnstartedRuntimeTest, StringInit) {
389 Thread* self = Thread::Current();
390 ScopedObjectAccess soa(self);
Vladimir Markoacb906d2018-05-30 10:23:49 +0100391 ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
Chang Xingfef27c22017-07-11 09:57:44 -0700392 ArtMethod* method =
Vladimir Markoba118822017-06-12 15:41:56 +0100393 klass->FindConstructor("(Ljava/lang/String;)V",
394 Runtime::Current()->GetClassLinker()->GetImagePointerSize());
395 ASSERT_TRUE(method != nullptr);
Jeff Hao400ce002015-05-29 10:53:17 -0700396
397 // create instruction data for invoke-direct {v0, v1} of method with fake index
398 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Jeff Hao400ce002015-05-29 10:53:17 -0700399
400 JValue result;
401 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
402 const char* base_string = "hello_world";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100403 StackHandleScope<2> hs(self);
404 Handle<mirror::String> string_arg =
405 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
406 Handle<mirror::String> reference_empty_string =
407 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
408 shadow_frame->SetVRegReference(0, reference_empty_string.Get());
409 shadow_frame->SetVRegReference(1, string_arg.Get());
Jeff Hao400ce002015-05-29 10:53:17 -0700410
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700411 interpreter::DoCall<false, false>(method,
412 self,
413 *shadow_frame,
414 Instruction::At(inst_data),
415 inst_data[0],
416 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100417 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Jeff Hao400ce002015-05-29 10:53:17 -0700418 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700419
420 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
421 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
422 string_arg->GetLength() * sizeof(uint8_t)), 0);
423 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
424 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
425 string_arg->GetLength() * sizeof(uint16_t)), 0);
426 } else {
427 bool equal = true;
428 for (int i = 0; i < string_arg->GetLength(); ++i) {
429 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
430 equal = false;
431 break;
432 }
433 }
434 EXPECT_EQ(equal, true);
435 }
Jeff Hao400ce002015-05-29 10:53:17 -0700436
437 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
438}
439
Andreas Gampe85a098a2016-03-31 13:30:53 -0700440// Tests the exceptions that should be checked before modifying the destination.
441// (Doesn't check the object vs primitive case ATM.)
442TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
443 Thread* self = Thread::Current();
444 ScopedObjectAccess soa(self);
445 JValue result;
446 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
447
448 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
449 // allocate.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100450 StackHandleScope<3> hs_misc(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100451 Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700452
453 StackHandleScope<3> hs_data(self);
454 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
455 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
456 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
457
458 Handle<mirror::ObjectArray<mirror::Object>> array(
459 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
460
461 RunArrayCopy(self, tmp, true, array.Get(), -1, array.Get(), 0, 0);
462 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), -1, 0);
463 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, -1);
464 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 0, 4);
465 RunArrayCopy(self, tmp, true, array.Get(), 0, array.Get(), 1, 3);
466 RunArrayCopy(self, tmp, true, array.Get(), 1, array.Get(), 0, 3);
467
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100468 Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
469 hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
470 RunArrayCopy(self, tmp, true, class_as_array.Get(), 0, array.Get(), 0, 0);
471 RunArrayCopy(self, tmp, true, array.Get(), 0, class_as_array.Get(), 0, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700472
473 ShadowFrame::DeleteDeoptimizedFrame(tmp);
474}
475
476TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
477 Thread* self = Thread::Current();
478 ScopedObjectAccess soa(self);
479 JValue result;
480 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
481
482 StackHandleScope<1> hs_object(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100483 Handle<mirror::Class> object_class(hs_object.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700484
485 // Simple test:
486 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
487 {
488 StackHandleScope<3> hs_src(self);
489 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
490 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
491 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
492
493 StackHandleScope<3> hs_dst(self);
494 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
495 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
496 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
497
498 StackHandleScope<3> hs_expected(self);
499 hs_expected.NewHandle(hs_dst.GetReference(0));
500 hs_expected.NewHandle(hs_dst.GetReference(1));
501 hs_expected.NewHandle(hs_src.GetReference(1));
502
503 RunArrayCopy(self,
504 tmp,
505 false,
506 object_class.Get(),
507 object_class.Get(),
508 hs_src,
509 1,
510 hs_dst,
511 2,
512 1,
513 hs_expected);
514 }
515
516 // Simple test:
517 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
518 {
519 StackHandleScope<3> hs_src(self);
520 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
521 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
522 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
523
524 StackHandleScope<3> hs_dst(self);
525 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
526 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
527 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
528
529 StackHandleScope<3> hs_expected(self);
530 hs_expected.NewHandle(hs_dst.GetReference(0));
531 hs_expected.NewHandle(hs_src.GetReference(1));
532 hs_expected.NewHandle(hs_dst.GetReference(2));
533
534 RunArrayCopy(self,
535 tmp,
536 false,
537 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100538 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700539 hs_src,
540 1,
541 hs_dst,
542 1,
543 1,
544 hs_expected);
545 }
546
547 // Simple test:
548 // [1,*,3] into [4,5,6] = [1,5,6] + exc
549 {
550 StackHandleScope<3> hs_src(self);
551 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
Vladimir Markoacb906d2018-05-30 10:23:49 +0100552 hs_src.NewHandle(GetClassRoot<mirror::String>());
Andreas Gampe85a098a2016-03-31 13:30:53 -0700553 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
554
555 StackHandleScope<3> hs_dst(self);
556 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
557 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
558 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
559
560 StackHandleScope<3> hs_expected(self);
561 hs_expected.NewHandle(hs_src.GetReference(0));
562 hs_expected.NewHandle(hs_dst.GetReference(1));
563 hs_expected.NewHandle(hs_dst.GetReference(2));
564
565 RunArrayCopy(self,
566 tmp,
567 true,
568 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100569 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700570 hs_src,
571 0,
572 hs_dst,
573 0,
574 3,
575 hs_expected);
576 }
577
578 ShadowFrame::DeleteDeoptimizedFrame(tmp);
579}
580
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700581TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
582 Thread* self = Thread::Current();
583 ScopedObjectAccess soa(self);
584
585 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
586
587 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
588 // suffixes).
589 constexpr const char* test_string = "-2147483646";
590 constexpr int32_t test_values[] = {
591 6,
592 46,
593 646,
594 3646,
595 83646,
596 483646,
597 7483646,
598 47483646,
599 147483646,
600 2147483646,
601 -2147483646
602 };
603
604 static_assert(arraysize(test_values) == 11U, "test_values");
605 CHECK_EQ(strlen(test_string), 11U);
606
607 for (size_t i = 0; i <= 10; ++i) {
608 const char* test_value = &test_string[10 - i];
609
610 StackHandleScope<1> hs_str(self);
611 Handle<mirror::String> h_str(
612 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
613 ASSERT_NE(h_str.Get(), nullptr);
614 ASSERT_FALSE(self->IsExceptionPending());
615
616 tmp->SetVRegReference(0, h_str.Get());
617
618 JValue result;
619 UnstartedIntegerParseInt(self, tmp, &result, 0);
620
621 ASSERT_FALSE(self->IsExceptionPending());
622 EXPECT_EQ(result.GetI(), test_values[i]);
623 }
624
625 ShadowFrame::DeleteDeoptimizedFrame(tmp);
626}
627
628// Right now the same as Integer.Parse
629TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
630 Thread* self = Thread::Current();
631 ScopedObjectAccess soa(self);
632
633 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, 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, &result, 0);
668
669 ASSERT_FALSE(self->IsExceptionPending());
670 EXPECT_EQ(result.GetJ(), test_values[i]);
671 }
672
673 ShadowFrame::DeleteDeoptimizedFrame(tmp);
674}
675
Andreas Gampe89e3b482016-04-12 18:07:36 -0700676TEST_F(UnstartedRuntimeTest, Ceil) {
677 Thread* self = Thread::Current();
678 ScopedObjectAccess soa(self);
679
680 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
681
682 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
683 constexpr double inf = std::numeric_limits<double>::infinity();
684 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
685 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
686 constexpr double test_pairs[][2] = {
687 { -0.0, -0.0 },
688 { 0.0, 0.0 },
689 { -0.5, -0.0 },
690 { -1.0, -1.0 },
691 { 0.5, 1.0 },
692 { 1.0, 1.0 },
693 { nan, nan },
694 { inf, inf },
695 { -inf, -inf },
696 { ld1, ld1 },
697 { ld2, ld2 }
698 };
699
700 TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));
701
702 ShadowFrame::DeleteDeoptimizedFrame(tmp);
703}
704
705TEST_F(UnstartedRuntimeTest, Floor) {
706 Thread* self = Thread::Current();
707 ScopedObjectAccess soa(self);
708
709 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(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(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));
730
731 ShadowFrame::DeleteDeoptimizedFrame(tmp);
732}
733
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700734TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
735 Thread* self = Thread::Current();
736 ScopedObjectAccess soa(self);
737
738 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
739
740 std::locale c_locale("C");
741
742 // Check ASCII.
743 for (uint32_t i = 0; i < 128; ++i) {
744 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
745 bool c_lower = std::islower(static_cast<char>(i), c_locale);
746 EXPECT_FALSE(c_upper && c_lower) << i;
747
748 // Check toLowerCase.
749 {
750 JValue result;
751 tmp->SetVReg(0, static_cast<int32_t>(i));
752 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
753 ASSERT_FALSE(self->IsExceptionPending());
754 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
755 if (c_lower) {
756 EXPECT_EQ(i, lower_result);
757 } else if (c_upper) {
758 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
759 lower_result);
760 } else {
761 EXPECT_EQ(i, lower_result);
762 }
763 }
764
765 // Check toUpperCase.
766 {
767 JValue result2;
768 tmp->SetVReg(0, static_cast<int32_t>(i));
769 UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
770 ASSERT_FALSE(self->IsExceptionPending());
771 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
772 if (c_upper) {
773 EXPECT_EQ(i, upper_result);
774 } else if (c_lower) {
775 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
776 upper_result);
777 } else {
778 EXPECT_EQ(i, upper_result);
779 }
780 }
781 }
782
783 // Check abort for other things. Can't test all.
784
785 PrepareForAborts();
786
787 for (uint32_t i = 128; i < 256; ++i) {
788 {
789 JValue result;
790 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700791 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700792 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700793 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700794 Runtime::Current()->ExitTransactionMode();
795 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700796 }
797 {
798 JValue result;
799 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700800 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700801 UnstartedCharacterToUpperCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700802 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700803 Runtime::Current()->ExitTransactionMode();
804 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700805 }
806 }
807 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
808 {
809 JValue result;
810 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700811 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700812 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700813 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700814 Runtime::Current()->ExitTransactionMode();
815 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700816 }
817 {
818 JValue result;
819 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700820 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700821 UnstartedCharacterToUpperCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700822 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700823 Runtime::Current()->ExitTransactionMode();
824 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700825 }
826 }
827
828 ShadowFrame::DeleteDeoptimizedFrame(tmp);
829}
830
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700831TEST_F(UnstartedRuntimeTest, Sin) {
832 Thread* self = Thread::Current();
833 ScopedObjectAccess soa(self);
834
835 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
836
837 // Test an important value, PI/6. That's the one we see in practice.
838 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
839 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
840
841 JValue result;
842 UnstartedMathSin(self, tmp, &result, 0);
843
844 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
845 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
846
847 ShadowFrame::DeleteDeoptimizedFrame(tmp);
848}
849
850TEST_F(UnstartedRuntimeTest, Cos) {
851 Thread* self = Thread::Current();
852 ScopedObjectAccess soa(self);
853
854 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
855
856 // Test an important value, PI/6. That's the one we see in practice.
857 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
858 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
859
860 JValue result;
861 UnstartedMathCos(self, tmp, &result, 0);
862
863 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
864 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
865
866 ShadowFrame::DeleteDeoptimizedFrame(tmp);
867}
868
869TEST_F(UnstartedRuntimeTest, Pow) {
Andreas Gampeb6795152016-04-21 17:23:31 -0700870 // Valgrind seems to get this wrong, actually. Disable for valgrind.
871 if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
872 return;
873 }
874
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700875 Thread* self = Thread::Current();
876 ScopedObjectAccess soa(self);
877
878 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
879
880 // Test an important pair.
881 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
882 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
883
884 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
885 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
886
887 JValue result;
888 UnstartedMathPow(self, tmp, &result, 0);
889
890 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
891 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
892
893 ShadowFrame::DeleteDeoptimizedFrame(tmp);
894}
895
Andreas Gampeae78c262017-02-01 20:40:44 -0800896TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
897 Thread* self = Thread::Current();
898 ScopedObjectAccess soa(self);
899
900 JValue result;
901 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
902
Vladimir Marko317892b2018-05-31 11:11:32 +0100903 ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
Andreas Gampeae78c262017-02-01 20:40:44 -0800904 shadow_frame->SetVRegReference(0, class_klass);
905 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
906 EXPECT_EQ(result.GetZ(), 0);
907
908 jobject class_loader = LoadDex("Nested");
909 StackHandleScope<1> hs(soa.Self());
910 Handle<mirror::ClassLoader> loader(
911 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100912 ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
Andreas Gampeae78c262017-02-01 20:40:44 -0800913 ASSERT_TRUE(c != nullptr);
914 shadow_frame->SetVRegReference(0, c);
915 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
916 EXPECT_EQ(result.GetZ(), 1);
917
918 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
919}
920
921TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
922 Thread* self = Thread::Current();
923 ScopedObjectAccess soa(self);
924
925 JValue result;
926 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
927
928 jobject class_loader = LoadDex("Nested");
929 StackHandleScope<4> hs(self);
930 Handle<mirror::ClassLoader> loader(
931 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
932
933 Handle<mirror::Class> nested_klass(hs.NewHandle(
934 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
935 Handle<mirror::Class> inner_klass(hs.NewHandle(
936 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
937 Handle<mirror::Class> anon_klass(hs.NewHandle(
938 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
939
940 shadow_frame->SetVRegReference(0, nested_klass.Get());
941 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
942 EXPECT_EQ(result.GetL(), nullptr);
943
944 shadow_frame->SetVRegReference(0, inner_klass.Get());
945 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
946 EXPECT_EQ(result.GetL(), nested_klass.Get());
947
948 shadow_frame->SetVRegReference(0, anon_klass.Get());
949 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
950 EXPECT_EQ(result.GetL(), nullptr);
951
952 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
953}
954
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800955TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
956 Thread* self = Thread::Current();
957 ScopedObjectAccess soa(self);
958
959 JValue result;
960 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
961
962 StackHandleScope<1> hs(self);
963 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
964
965 // Positive test. See that We get something for float conversion.
966 {
967 Handle<mirror::Class> floating_decimal = hs.NewHandle(
968 class_linker->FindClass(self,
969 "Lsun/misc/FloatingDecimal;",
970 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800971 ASSERT_TRUE(floating_decimal != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800972 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
973
Vladimir Markoba118822017-06-12 15:41:56 +0100974 ArtMethod* caller_method = floating_decimal->FindClassMethod(
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800975 "getBinaryToASCIIBuffer",
976 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
977 class_linker->GetImagePointerSize());
978 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
979 ASSERT_TRUE(caller_method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100980 ASSERT_TRUE(caller_method->IsDirect());
981 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800982 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
983 shadow_frame->SetLink(caller_frame);
984
985 UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
986 EXPECT_TRUE(result.GetL() != nullptr);
987 EXPECT_FALSE(self->IsExceptionPending());
988
989 ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
990 }
991
992 // Negative test.
993 PrepareForAborts();
994
995 {
996 // Just use a method in Class.
Vladimir Marko317892b2018-05-31 11:11:32 +0100997 ObjPtr<mirror::Class> class_class = GetClassRoot<mirror::Class>();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800998 ArtMethod* caller_method =
999 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
1000 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
1001 shadow_frame->SetLink(caller_frame);
1002
Chang Xing16d1dd82017-07-20 17:56:26 -07001003 Runtime::Current()->EnterTransactionMode();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001004 UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001005 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001006 Runtime::Current()->ExitTransactionMode();
1007 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001008 self->ClearException();
1009
1010 ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
1011 }
1012
1013 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1014}
1015
1016TEST_F(UnstartedRuntimeTest, FloatConversion) {
1017 Thread* self = Thread::Current();
1018 ScopedObjectAccess soa(self);
1019
1020 StackHandleScope<1> hs(self);
1021 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1022 Handle<mirror::Class> double_class = hs.NewHandle(
1023 class_linker->FindClass(self,
1024 "Ljava/lang/Double;",
1025 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001026 ASSERT_TRUE(double_class != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001027 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1028
Vladimir Markoba118822017-06-12 15:41:56 +01001029 ArtMethod* method = double_class->FindClassMethod("toString",
1030 "(D)Ljava/lang/String;",
1031 class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001032 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +01001033 ASSERT_TRUE(method->IsDirect());
1034 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001035
1036 // create instruction data for invoke-direct {v0, v1} of method with fake index
1037 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001038
1039 JValue result;
1040 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
1041 shadow_frame->SetVRegDouble(0, 1.23);
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001042 interpreter::DoCall<false, false>(method,
1043 self,
1044 *shadow_frame,
1045 Instruction::At(inst_data),
1046 inst_data[0],
1047 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001048 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001049 ASSERT_TRUE(string_result != nullptr);
1050
1051 std::string mod_utf = string_result->ToModifiedUtf8();
1052 EXPECT_EQ("1.23", mod_utf);
1053
1054 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1055}
1056
Andreas Gampebad529d2017-02-13 18:52:10 -08001057TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1058 Thread* self = Thread::Current();
1059 ScopedObjectAccess soa(self);
1060
1061 JValue result;
1062 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1063
1064 StackHandleScope<1> hs(self);
1065 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1066 Handle<mirror::Class> thread_class = hs.NewHandle(
1067 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1068 ASSERT_TRUE(thread_class.Get() != nullptr);
1069 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1070
1071 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1072 // be recreated at runtime).
1073 PrepareForAborts();
1074
1075 {
Chang Xing16d1dd82017-07-20 17:56:26 -07001076 Runtime::Current()->EnterTransactionMode();
Andreas Gampebad529d2017-02-13 18:52:10 -08001077 UnstartedThreadCurrentThread(self, shadow_frame, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001078 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampebad529d2017-02-13 18:52:10 -08001079 Runtime::Current()->ExitTransactionMode();
1080 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampebad529d2017-02-13 18:52:10 -08001081 self->ClearException();
1082 }
1083
1084 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1085}
1086
1087TEST_F(UnstartedRuntimeTest, LogManager) {
1088 Thread* self = Thread::Current();
1089 ScopedObjectAccess soa(self);
1090
1091 StackHandleScope<1> hs(self);
1092 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1093 Handle<mirror::Class> log_manager_class = hs.NewHandle(
Andreas Gampe9486a162017-02-16 15:17:47 -08001094 class_linker->FindClass(self,
1095 "Ljava/util/logging/LogManager;",
1096 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampebad529d2017-02-13 18:52:10 -08001097 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1098 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1099}
1100
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001101class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1102 public:
1103 template <typename T>
1104 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1105 Thread* self = Thread::Current();
1106 ScopedObjectAccess soa(self);
1107
1108 // Ensure that Class is initialized.
1109 {
1110 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1111 StackHandleScope<1> hs(self);
Vladimir Marko317892b2018-05-31 11:11:32 +01001112 Handle<mirror::Class> h_class = hs.NewHandle(GetClassRoot<mirror::Class>());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001113 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1114 }
1115
1116 // A selection of classes from different core classpath components.
1117 constexpr const char* kTestCases[] = {
1118 "java.net.CookieManager", // From libcore.
1119 "dalvik.system.ClassExt", // From libart.
1120 };
1121
1122 if (in_transaction) {
1123 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1124 // classes isn't transactional. Load them ahead of time.
1125 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1126 for (const char* name : kTestCases) {
1127 class_linker->FindClass(self,
1128 DotToDescriptor(name).c_str(),
1129 ScopedNullHandle<mirror::ClassLoader>());
1130 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1131 }
1132 }
1133
1134 if (!should_succeed) {
1135 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1136 // be recreated at runtime).
1137 PrepareForAborts();
1138 }
1139
1140 JValue result;
1141 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1142
1143 for (const char* name : kTestCases) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001144 ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001145 CHECK(name_string != nullptr);
1146
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001147 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001148 Runtime::Current()->EnterTransactionMode();
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001149 }
1150 CHECK(!self->IsExceptionPending());
1151
1152 runner(self, shadow_frame, name_string, &result);
1153
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001154 if (should_succeed) {
1155 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1156 CHECK(result.GetL() != nullptr) << name;
1157 } else {
1158 CHECK(self->IsExceptionPending()) << name;
1159 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001160 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001161 }
1162 self->ClearException();
1163 }
Chang Xing16d1dd82017-07-20 17:56:26 -07001164
1165 if (in_transaction) {
1166 Runtime::Current()->ExitTransactionMode();
1167 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001168 }
1169
1170 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1171 }
1172
1173 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1174 Thread* self = Thread::Current();
1175 StackHandleScope<2> hs(self);
1176 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1177
1178 {
1179 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1180
1181 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1182 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1183 class_linker->FindClass(self,
1184 "Ljava/lang/BootClassLoader;",
1185 ScopedNullHandle<mirror::ClassLoader>()));
1186 CHECK(boot_cp_class != nullptr);
1187 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1188
1189 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1190 CHECK(boot_cp != nullptr);
1191
Vladimir Markoba118822017-06-12 15:41:56 +01001192 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1193 "()V", class_linker->GetImagePointerSize());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001194 CHECK(boot_cp_init != nullptr);
1195
1196 JValue result;
1197 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0);
1198 shadow_frame->SetVRegReference(0, boot_cp.Get());
1199
1200 // create instruction data for invoke-direct {v0} of method with fake index
1201 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001202
1203 interpreter::DoCall<false, false>(boot_cp_init,
1204 self,
1205 *shadow_frame,
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001206 Instruction::At(inst_data),
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001207 inst_data[0],
1208 &result);
1209 CHECK(!self->IsExceptionPending());
1210
1211 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1212 }
1213
1214 return boot_cp.Get();
1215 }
1216};
1217
1218TEST_F(UnstartedClassForNameTest, ClassForName) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001219 auto runner = [](Thread* self,
1220 ShadowFrame* shadow_frame,
1221 ObjPtr<mirror::String> name,
1222 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001223 shadow_frame->SetVRegReference(0, name);
1224 UnstartedClassForName(self, shadow_frame, result, 0);
1225 };
1226 RunTest(runner, false, true);
1227}
1228
1229TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001230 auto runner = [](Thread* self,
1231 ShadowFrame* shadow_frame,
1232 ObjPtr<mirror::String> name,
1233 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001234 shadow_frame->SetVRegReference(0, name);
1235 shadow_frame->SetVReg(1, 0);
1236 shadow_frame->SetVRegReference(2, nullptr);
1237 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1238 };
1239 RunTest(runner, false, true);
1240}
1241
1242TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1243 Thread* self = Thread::Current();
1244 ScopedObjectAccess soa(self);
1245
1246 StackHandleScope<1> hs(self);
1247 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1248
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001249 auto runner = [&](Thread* th,
1250 ShadowFrame* shadow_frame,
1251 ObjPtr<mirror::String> name,
1252 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001253 shadow_frame->SetVRegReference(0, name);
1254 shadow_frame->SetVReg(1, 0);
1255 shadow_frame->SetVRegReference(2, boot_cp.Get());
1256 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1257 };
1258 RunTest(runner, false, true);
1259}
1260
1261TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1262 Thread* self = Thread::Current();
1263 ScopedObjectAccess soa(self);
1264
1265 StackHandleScope<1> hs(self);
1266 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1267
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001268 auto runner = [&](Thread* th,
1269 ShadowFrame* shadow_frame,
1270 ObjPtr<mirror::String> name,
1271 JValue* result)
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001272 REQUIRES_SHARED(Locks::mutator_lock_) {
1273 shadow_frame->SetVRegReference(0, name);
1274 shadow_frame->SetVReg(1, 0);
1275 shadow_frame->SetVRegReference(2, boot_cp.Get());
1276 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1277 };
1278 RunTest(runner, true, true);
1279}
1280
1281TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1282 Thread* self = Thread::Current();
1283 ScopedObjectAccess soa(self);
1284
1285 StackHandleScope<2> hs(self);
1286 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1287 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1288 ASSERT_TRUE(path_jobj != nullptr);
1289 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1290 self->DecodeJObject(path_jobj)->AsClassLoader());
1291
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001292 auto runner = [&](Thread* th,
1293 ShadowFrame* shadow_frame,
1294 ObjPtr<mirror::String> name,
1295 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001296 shadow_frame->SetVRegReference(0, name);
1297 shadow_frame->SetVReg(1, 0);
1298 shadow_frame->SetVRegReference(2, path_cp.Get());
1299 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1300 };
1301 RunTest(runner, true, false);
1302}
1303
Andreas Gampe9486a162017-02-16 15:17:47 -08001304TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1305 Thread* self = Thread::Current();
1306 ScopedObjectAccess soa(self);
1307
1308 StackHandleScope<1> hs(self);
1309 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1310 Handle<mirror::Class> list_class = hs.NewHandle(
1311 class_linker->FindClass(self,
1312 "Ljava/util/List;",
1313 ScopedNullHandle<mirror::ClassLoader>()));
1314 ASSERT_TRUE(list_class.Get() != nullptr);
1315 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1316
1317 JValue result;
1318 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1319
1320 shadow_frame->SetVRegReference(0, list_class.Get());
1321 UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0);
1322 ASSERT_TRUE(result.GetL() != nullptr);
1323 ASSERT_FALSE(self->IsExceptionPending());
1324
1325 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1326
1327 ASSERT_TRUE(result.GetL()->IsObjectArray());
1328 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1329 result.GetL()->AsObjectArray<mirror::Object>();
1330 std::ostringstream oss;
1331 for (int32_t i = 0; i != array->GetLength(); ++i) {
1332 ObjPtr<mirror::Object> elem = array->Get(i);
1333 ASSERT_TRUE(elem != nullptr);
1334 ASSERT_TRUE(elem->IsString());
1335 oss << elem->AsString()->ToModifiedUtf8();
1336 }
1337 std::string output_string = oss.str();
1338 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1339}
1340
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001341TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1342 Thread* self = Thread::Current();
1343 ScopedObjectAccess soa(self);
1344
1345 StackHandleScope<4> hs(self);
1346 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1347
1348 // Get Throwable.
Vladimir Markoadbceb72018-05-29 14:34:14 +01001349 Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001350 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1351
1352 // Get an input object.
1353 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1354
1355 // Find the constructor.
Vladimir Markoba118822017-06-12 15:41:56 +01001356 ArtMethod* throw_cons = throw_class->FindConstructor(
1357 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001358 ASSERT_TRUE(throw_cons != nullptr);
Chang Xingfef27c22017-07-11 09:57:44 -07001359 Handle<mirror::Constructor> cons;
1360 if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1361 cons = hs.NewHandle(
1362 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1363 ASSERT_TRUE(cons != nullptr);
1364 } else {
1365 cons = hs.NewHandle(
1366 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1367 ASSERT_TRUE(cons != nullptr);
1368 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001369
1370 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
Andreas Gampec6ea7d02017-02-01 16:46:28 -08001371 mirror::ObjectArray<mirror::Object>::Alloc(
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001372 self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001373 ASSERT_TRUE(args != nullptr);
1374 args->Set(0, input.Get());
1375
1376 // OK, we're ready now.
1377 JValue result;
1378 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1379 shadow_frame->SetVRegReference(0, cons.Get());
1380 shadow_frame->SetVRegReference(1, args.Get());
1381 UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0);
1382
1383 ASSERT_TRUE(result.GetL() != nullptr);
1384 ASSERT_FALSE(self->IsExceptionPending());
1385
1386 // Should be a new object.
1387 ASSERT_NE(result.GetL(), input.Get());
Vladimir Markoadbceb72018-05-29 14:34:14 +01001388 // Should be of type Throwable.
1389 ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001390 // Should have the right string.
1391 ObjPtr<mirror::String> result_msg =
1392 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001393 EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001394
1395 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1396}
1397
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001398TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1399 Thread* self = Thread::Current();
1400 ScopedObjectAccess soa(self);
1401 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1402
1403 JValue result;
1404 UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1405
1406 EXPECT_EQ(0, result.GetI());
1407 ASSERT_FALSE(self->IsExceptionPending());
1408
1409 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001410 tmp->SetVRegReference(0, str);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001411 UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1412 EXPECT_NE(0, result.GetI());
1413 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1414 ASSERT_FALSE(self->IsExceptionPending());
1415
1416 ShadowFrame::DeleteDeoptimizedFrame(tmp);
1417}
1418
Andreas Gampe799681b2015-05-15 19:24:12 -07001419} // namespace interpreter
1420} // namespace art