blob: 860de2c28bc8050416ec81e2bb921e4526b33710 [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"
26#include "common_runtime_test.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080027#include "dex/descriptors_names.h"
David Sehr9e734c72018-01-04 17:56:19 -080028#include "dex/dex_instruction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070029#include "handle.h"
30#include "handle_scope-inl.h"
Jeff Hao400ce002015-05-29 10:53:17 -070031#include "interpreter/interpreter_common.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070032#include "mirror/class_loader.h"
Andreas Gampe9486a162017-02-16 15:17:47 -080033#include "mirror/object-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070034#include "mirror/object_array-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070035#include "mirror/string-inl.h"
36#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070037#include "scoped_thread_state_change-inl.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010038#include "shadow_frame-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070039#include "thread.h"
Andreas Gampe8ce9c302016-04-15 21:24:28 -070040#include "transaction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070041
42namespace art {
43namespace interpreter {
44
45class UnstartedRuntimeTest : public CommonRuntimeTest {
46 protected:
47 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
48 // test friends.
49
50 // Methods that intercept available libcore implementations.
51#define UNSTARTED_DIRECT(Name, SigIgnored) \
52 static void Unstarted ## Name(Thread* self, \
53 ShadowFrame* shadow_frame, \
54 JValue* result, \
55 size_t arg_offset) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070056 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070057 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
58 }
59#include "unstarted_runtime_list.h"
60 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
61#undef UNSTARTED_RUNTIME_DIRECT_LIST
62#undef UNSTARTED_RUNTIME_JNI_LIST
63#undef UNSTARTED_DIRECT
64
65 // Methods that are native.
Mathieu Chartiere401d142015-04-22 13:56:20 -070066#define UNSTARTED_JNI(Name, SigIgnored) \
Andreas Gampe799681b2015-05-15 19:24:12 -070067 static void UnstartedJNI ## Name(Thread* self, \
Mathieu Chartiere401d142015-04-22 13:56:20 -070068 ArtMethod* method, \
Andreas Gampe799681b2015-05-15 19:24:12 -070069 mirror::Object* receiver, \
70 uint32_t* args, \
71 JValue* result) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070072 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070073 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
74 }
75#include "unstarted_runtime_list.h"
76 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
77#undef UNSTARTED_RUNTIME_DIRECT_LIST
78#undef UNSTARTED_RUNTIME_JNI_LIST
79#undef UNSTARTED_JNI
Andreas Gampe85a098a2016-03-31 13:30:53 -070080
81 // Helpers for ArrayCopy.
82 //
83 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
84 // of three everywhere. That is enough to test all cases.
85
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010086 static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
Andreas Gampe85a098a2016-03-31 13:30:53 -070087 Thread* self,
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070088 ObjPtr<mirror::Class> component_type,
Andreas Gampe85a098a2016-03-31 13:30:53 -070089 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070090 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -070091 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070092 ObjPtr<mirror::Class> array_type =
93 runtime->GetClassLinker()->FindArrayClass(self, &component_type);
Andreas Gampe85a098a2016-03-31 13:30:53 -070094 CHECK(array_type != nullptr);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070095 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
Andreas Gampe85a098a2016-03-31 13:30:53 -070096 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
97 CHECK(result != nullptr);
98 for (size_t i = 0; i < 3; ++i) {
99 result->Set(static_cast<int32_t>(i), data.GetReference(i));
100 CHECK(!self->IsExceptionPending());
101 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100102 return result;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700103 }
104
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100105 static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700106 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700107 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700108 CHECK_EQ(array->GetLength(), 3);
109 CHECK_EQ(data.NumberOfReferences(), 3U);
110 for (size_t i = 0; i < 3; ++i) {
111 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
112 }
113 }
114
115 void RunArrayCopy(Thread* self,
116 ShadowFrame* tmp,
117 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100118 ObjPtr<mirror::ObjectArray<mirror::Object>> src,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700119 int32_t src_pos,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100120 ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700121 int32_t dst_pos,
122 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700123 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700124 JValue result;
125 tmp->SetVRegReference(0, src);
126 tmp->SetVReg(1, src_pos);
127 tmp->SetVRegReference(2, dst);
128 tmp->SetVReg(3, dst_pos);
129 tmp->SetVReg(4, length);
130 UnstartedSystemArraycopy(self, tmp, &result, 0);
131 bool exception_pending = self->IsExceptionPending();
132 EXPECT_EQ(exception_pending, expect_exception);
133 if (exception_pending) {
134 self->ClearException();
135 }
136 }
137
138 void RunArrayCopy(Thread* self,
139 ShadowFrame* tmp,
140 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100141 ObjPtr<mirror::Class> src_component_class,
142 ObjPtr<mirror::Class> dst_component_class,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700143 const StackHandleScope<3>& src_data,
144 int32_t src_pos,
145 const StackHandleScope<3>& dst_data,
146 int32_t dst_pos,
147 int32_t length,
148 const StackHandleScope<3>& expected_result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700149 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700150 StackHandleScope<3> hs_misc(self);
151 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
152
153 Handle<mirror::ObjectArray<mirror::Object>> src_handle(
154 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
155
156 Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
157 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
158
159 RunArrayCopy(self,
160 tmp,
161 expect_exception,
162 src_handle.Get(),
163 src_pos,
164 dst_handle.Get(),
165 dst_pos,
166 length);
167 CheckObjectArray(dst_handle.Get(), expected_result);
168 }
Andreas Gampe89e3b482016-04-12 18:07:36 -0700169
170 void TestCeilFloor(bool ceil,
171 Thread* self,
172 ShadowFrame* tmp,
173 double const test_pairs[][2],
174 size_t num_pairs)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700175 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700176 for (size_t i = 0; i < num_pairs; ++i) {
177 tmp->SetVRegDouble(0, test_pairs[i][0]);
178
179 JValue result;
180 if (ceil) {
181 UnstartedMathCeil(self, tmp, &result, 0);
182 } else {
183 UnstartedMathFloor(self, tmp, &result, 0);
184 }
185
186 ASSERT_FALSE(self->IsExceptionPending());
187
188 // We want precise results.
189 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
190 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
191 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
192 }
193 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700194
195 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
196 // loading code doesn't work under transactions.
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700197 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700198 mirror::Object* result = Runtime::Current()->GetClassLinker()->FindClass(
199 Thread::Current(),
200 Transaction::kAbortExceptionSignature,
201 ScopedNullHandle<mirror::ClassLoader>());
202 CHECK(result != nullptr);
203 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700204};
205
206TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
207 Thread* self = Thread::Current();
208
209 ScopedObjectAccess soa(self);
210 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
211 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
212 const uint8_t* base_ptr = base_array;
213
214 JValue result;
215 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
216
217 for (int32_t i = 0; i < kBaseLen; ++i) {
218 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
219
220 UnstartedMemoryPeekByte(self, tmp, &result, 0);
221
222 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
223 }
224
225 ShadowFrame::DeleteDeoptimizedFrame(tmp);
226}
227
228TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
229 Thread* self = Thread::Current();
230
231 ScopedObjectAccess soa(self);
232 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
233 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
234 const uint8_t* base_ptr = base_array;
235
236 JValue result;
237 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
238
239 int32_t adjusted_length = kBaseLen - sizeof(int16_t);
240 for (int32_t i = 0; i < adjusted_length; ++i) {
241 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
242
243 UnstartedMemoryPeekShort(self, tmp, &result, 0);
244
245 typedef int16_t unaligned_short __attribute__ ((aligned (1)));
246 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
247 EXPECT_EQ(result.GetS(), *short_ptr);
248 }
249
250 ShadowFrame::DeleteDeoptimizedFrame(tmp);
251}
252
253TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
254 Thread* self = Thread::Current();
255
256 ScopedObjectAccess soa(self);
257 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
258 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
259 const uint8_t* base_ptr = base_array;
260
261 JValue result;
262 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
263
264 int32_t adjusted_length = kBaseLen - sizeof(int32_t);
265 for (int32_t i = 0; i < adjusted_length; ++i) {
266 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
267
268 UnstartedMemoryPeekInt(self, tmp, &result, 0);
269
270 typedef int32_t unaligned_int __attribute__ ((aligned (1)));
271 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
272 EXPECT_EQ(result.GetI(), *int_ptr);
273 }
274
275 ShadowFrame::DeleteDeoptimizedFrame(tmp);
276}
277
278TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
279 Thread* self = Thread::Current();
280
281 ScopedObjectAccess soa(self);
282 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
283 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
284 const uint8_t* base_ptr = base_array;
285
286 JValue result;
287 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
288
289 int32_t adjusted_length = kBaseLen - sizeof(int64_t);
290 for (int32_t i = 0; i < adjusted_length; ++i) {
291 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
292
293 UnstartedMemoryPeekLong(self, tmp, &result, 0);
294
295 typedef int64_t unaligned_long __attribute__ ((aligned (1)));
296 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
297 EXPECT_EQ(result.GetJ(), *long_ptr);
298 }
299
300 ShadowFrame::DeleteDeoptimizedFrame(tmp);
301}
302
303TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
304 Thread* self = Thread::Current();
305
306 ScopedObjectAccess soa(self);
307 StackHandleScope<2> hs(self);
308 // TODO: Actual UTF.
309 constexpr const char base_string[] = "abcdefghijklmnop";
310 Handle<mirror::String> h_test_string(hs.NewHandle(
311 mirror::String::AllocFromModifiedUtf8(self, base_string)));
312 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
313 Handle<mirror::CharArray> h_char_array(hs.NewHandle(
314 mirror::CharArray::Alloc(self, kBaseLen)));
315 // A buffer so we can make sure we only modify the elements targetted.
316 uint16_t buf[kBaseLen];
317
318 JValue result;
319 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
320
321 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
322 for (int32_t count = 0; count <= kBaseLen; ++count) {
323 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
324 // Only do it when in bounds.
325 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
326 tmp->SetVRegReference(0, h_test_string.Get());
327 tmp->SetVReg(1, start_index);
328 tmp->SetVReg(2, count);
329 tmp->SetVRegReference(3, h_char_array.Get());
330 tmp->SetVReg(3, trg_offset);
331
332 // Copy the char_array into buf.
333 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
334
335 UnstartedStringCharAt(self, tmp, &result, 0);
336
337 uint16_t* data = h_char_array->GetData();
338
339 bool success = true;
340
341 // First segment should be unchanged.
342 for (int32_t i = 0; i < trg_offset; ++i) {
343 success = success && (data[i] == buf[i]);
344 }
345 // Second segment should be a copy.
346 for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
347 success = success && (data[i] == buf[i - trg_offset + start_index]);
348 }
349 // Third segment should be unchanged.
350 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
351 success = success && (data[i] == buf[i]);
352 }
353
354 EXPECT_TRUE(success);
355 }
356 }
357 }
358 }
359
360 ShadowFrame::DeleteDeoptimizedFrame(tmp);
361}
362
363TEST_F(UnstartedRuntimeTest, StringCharAt) {
364 Thread* self = Thread::Current();
365
366 ScopedObjectAccess soa(self);
367 // TODO: Actual UTF.
368 constexpr const char* base_string = "abcdefghijklmnop";
369 int32_t base_len = static_cast<int32_t>(strlen(base_string));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100370 ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
Andreas Gampe799681b2015-05-15 19:24:12 -0700371
372 JValue result;
373 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
374
375 for (int32_t i = 0; i < base_len; ++i) {
376 tmp->SetVRegReference(0, test_string);
377 tmp->SetVReg(1, i);
378
379 UnstartedStringCharAt(self, tmp, &result, 0);
380
381 EXPECT_EQ(result.GetI(), base_string[i]);
382 }
383
384 ShadowFrame::DeleteDeoptimizedFrame(tmp);
385}
386
Jeff Hao400ce002015-05-29 10:53:17 -0700387TEST_F(UnstartedRuntimeTest, StringInit) {
388 Thread* self = Thread::Current();
389 ScopedObjectAccess soa(self);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100390 ObjPtr<mirror::Class> klass = mirror::String::GetJavaLangString();
Chang Xingfef27c22017-07-11 09:57:44 -0700391 ArtMethod* method =
Vladimir Markoba118822017-06-12 15:41:56 +0100392 klass->FindConstructor("(Ljava/lang/String;)V",
393 Runtime::Current()->GetClassLinker()->GetImagePointerSize());
394 ASSERT_TRUE(method != nullptr);
Jeff Hao400ce002015-05-29 10:53:17 -0700395
396 // create instruction data for invoke-direct {v0, v1} of method with fake index
397 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Jeff Hao400ce002015-05-29 10:53:17 -0700398
399 JValue result;
400 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
401 const char* base_string = "hello_world";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100402 StackHandleScope<2> hs(self);
403 Handle<mirror::String> string_arg =
404 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
405 Handle<mirror::String> reference_empty_string =
406 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
407 shadow_frame->SetVRegReference(0, reference_empty_string.Get());
408 shadow_frame->SetVRegReference(1, string_arg.Get());
Jeff Hao400ce002015-05-29 10:53:17 -0700409
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700410 interpreter::DoCall<false, false>(method,
411 self,
412 *shadow_frame,
413 Instruction::At(inst_data),
414 inst_data[0],
415 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100416 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Jeff Hao400ce002015-05-29 10:53:17 -0700417 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700418
419 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
420 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
421 string_arg->GetLength() * sizeof(uint8_t)), 0);
422 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
423 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
424 string_arg->GetLength() * sizeof(uint16_t)), 0);
425 } else {
426 bool equal = true;
427 for (int i = 0; i < string_arg->GetLength(); ++i) {
428 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
429 equal = false;
430 break;
431 }
432 }
433 EXPECT_EQ(equal, true);
434 }
Jeff Hao400ce002015-05-29 10:53:17 -0700435
436 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
437}
438
Andreas Gampe85a098a2016-03-31 13:30:53 -0700439// Tests the exceptions that should be checked before modifying the destination.
440// (Doesn't check the object vs primitive case ATM.)
441TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
442 Thread* self = Thread::Current();
443 ScopedObjectAccess soa(self);
444 JValue result;
445 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
446
447 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
448 // allocate.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100449 StackHandleScope<3> hs_misc(self);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700450 Handle<mirror::Class> object_class(
451 hs_misc.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
452
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);
483 Handle<mirror::Class> object_class(
484 hs_object.NewHandle(mirror::Class::GetJavaLangClass()->GetSuperClass()));
485
486 // Simple test:
487 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
488 {
489 StackHandleScope<3> hs_src(self);
490 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
491 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
492 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
493
494 StackHandleScope<3> hs_dst(self);
495 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
496 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
497 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
498
499 StackHandleScope<3> hs_expected(self);
500 hs_expected.NewHandle(hs_dst.GetReference(0));
501 hs_expected.NewHandle(hs_dst.GetReference(1));
502 hs_expected.NewHandle(hs_src.GetReference(1));
503
504 RunArrayCopy(self,
505 tmp,
506 false,
507 object_class.Get(),
508 object_class.Get(),
509 hs_src,
510 1,
511 hs_dst,
512 2,
513 1,
514 hs_expected);
515 }
516
517 // Simple test:
518 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
519 {
520 StackHandleScope<3> hs_src(self);
521 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
522 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
523 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
524
525 StackHandleScope<3> hs_dst(self);
526 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
527 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
528 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
529
530 StackHandleScope<3> hs_expected(self);
531 hs_expected.NewHandle(hs_dst.GetReference(0));
532 hs_expected.NewHandle(hs_src.GetReference(1));
533 hs_expected.NewHandle(hs_dst.GetReference(2));
534
535 RunArrayCopy(self,
536 tmp,
537 false,
538 object_class.Get(),
539 mirror::String::GetJavaLangString(),
540 hs_src,
541 1,
542 hs_dst,
543 1,
544 1,
545 hs_expected);
546 }
547
548 // Simple test:
549 // [1,*,3] into [4,5,6] = [1,5,6] + exc
550 {
551 StackHandleScope<3> hs_src(self);
552 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
553 hs_src.NewHandle(mirror::String::GetJavaLangString());
554 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
555
556 StackHandleScope<3> hs_dst(self);
557 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
558 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
559 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
560
561 StackHandleScope<3> hs_expected(self);
562 hs_expected.NewHandle(hs_src.GetReference(0));
563 hs_expected.NewHandle(hs_dst.GetReference(1));
564 hs_expected.NewHandle(hs_dst.GetReference(2));
565
566 RunArrayCopy(self,
567 tmp,
568 true,
569 object_class.Get(),
570 mirror::String::GetJavaLangString(),
571 hs_src,
572 0,
573 hs_dst,
574 0,
575 3,
576 hs_expected);
577 }
578
579 ShadowFrame::DeleteDeoptimizedFrame(tmp);
580}
581
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700582TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
583 Thread* self = Thread::Current();
584 ScopedObjectAccess soa(self);
585
586 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
587
588 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
589 // suffixes).
590 constexpr const char* test_string = "-2147483646";
591 constexpr int32_t test_values[] = {
592 6,
593 46,
594 646,
595 3646,
596 83646,
597 483646,
598 7483646,
599 47483646,
600 147483646,
601 2147483646,
602 -2147483646
603 };
604
605 static_assert(arraysize(test_values) == 11U, "test_values");
606 CHECK_EQ(strlen(test_string), 11U);
607
608 for (size_t i = 0; i <= 10; ++i) {
609 const char* test_value = &test_string[10 - i];
610
611 StackHandleScope<1> hs_str(self);
612 Handle<mirror::String> h_str(
613 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
614 ASSERT_NE(h_str.Get(), nullptr);
615 ASSERT_FALSE(self->IsExceptionPending());
616
617 tmp->SetVRegReference(0, h_str.Get());
618
619 JValue result;
620 UnstartedIntegerParseInt(self, tmp, &result, 0);
621
622 ASSERT_FALSE(self->IsExceptionPending());
623 EXPECT_EQ(result.GetI(), test_values[i]);
624 }
625
626 ShadowFrame::DeleteDeoptimizedFrame(tmp);
627}
628
629// Right now the same as Integer.Parse
630TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
631 Thread* self = Thread::Current();
632 ScopedObjectAccess soa(self);
633
634 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
635
636 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
637 // suffixes).
638 constexpr const char* test_string = "-2147483646";
639 constexpr int64_t test_values[] = {
640 6,
641 46,
642 646,
643 3646,
644 83646,
645 483646,
646 7483646,
647 47483646,
648 147483646,
649 2147483646,
650 -2147483646
651 };
652
653 static_assert(arraysize(test_values) == 11U, "test_values");
654 CHECK_EQ(strlen(test_string), 11U);
655
656 for (size_t i = 0; i <= 10; ++i) {
657 const char* test_value = &test_string[10 - i];
658
659 StackHandleScope<1> hs_str(self);
660 Handle<mirror::String> h_str(
661 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
662 ASSERT_NE(h_str.Get(), nullptr);
663 ASSERT_FALSE(self->IsExceptionPending());
664
665 tmp->SetVRegReference(0, h_str.Get());
666
667 JValue result;
668 UnstartedLongParseLong(self, tmp, &result, 0);
669
670 ASSERT_FALSE(self->IsExceptionPending());
671 EXPECT_EQ(result.GetJ(), test_values[i]);
672 }
673
674 ShadowFrame::DeleteDeoptimizedFrame(tmp);
675}
676
Andreas Gampe89e3b482016-04-12 18:07:36 -0700677TEST_F(UnstartedRuntimeTest, Ceil) {
678 Thread* self = Thread::Current();
679 ScopedObjectAccess soa(self);
680
681 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
682
683 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
684 constexpr double inf = std::numeric_limits<double>::infinity();
685 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
686 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
687 constexpr double test_pairs[][2] = {
688 { -0.0, -0.0 },
689 { 0.0, 0.0 },
690 { -0.5, -0.0 },
691 { -1.0, -1.0 },
692 { 0.5, 1.0 },
693 { 1.0, 1.0 },
694 { nan, nan },
695 { inf, inf },
696 { -inf, -inf },
697 { ld1, ld1 },
698 { ld2, ld2 }
699 };
700
701 TestCeilFloor(true /* ceil */, self, tmp, test_pairs, arraysize(test_pairs));
702
703 ShadowFrame::DeleteDeoptimizedFrame(tmp);
704}
705
706TEST_F(UnstartedRuntimeTest, Floor) {
707 Thread* self = Thread::Current();
708 ScopedObjectAccess soa(self);
709
710 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
711
712 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
713 constexpr double inf = std::numeric_limits<double>::infinity();
714 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
715 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
716 constexpr double test_pairs[][2] = {
717 { -0.0, -0.0 },
718 { 0.0, 0.0 },
719 { -0.5, -1.0 },
720 { -1.0, -1.0 },
721 { 0.5, 0.0 },
722 { 1.0, 1.0 },
723 { nan, nan },
724 { inf, inf },
725 { -inf, -inf },
726 { ld1, ld1 },
727 { ld2, ld2 }
728 };
729
730 TestCeilFloor(false /* floor */, self, tmp, test_pairs, arraysize(test_pairs));
731
732 ShadowFrame::DeleteDeoptimizedFrame(tmp);
733}
734
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700735TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
736 Thread* self = Thread::Current();
737 ScopedObjectAccess soa(self);
738
739 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
740
741 std::locale c_locale("C");
742
743 // Check ASCII.
744 for (uint32_t i = 0; i < 128; ++i) {
745 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
746 bool c_lower = std::islower(static_cast<char>(i), c_locale);
747 EXPECT_FALSE(c_upper && c_lower) << i;
748
749 // Check toLowerCase.
750 {
751 JValue result;
752 tmp->SetVReg(0, static_cast<int32_t>(i));
753 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
754 ASSERT_FALSE(self->IsExceptionPending());
755 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
756 if (c_lower) {
757 EXPECT_EQ(i, lower_result);
758 } else if (c_upper) {
759 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
760 lower_result);
761 } else {
762 EXPECT_EQ(i, lower_result);
763 }
764 }
765
766 // Check toUpperCase.
767 {
768 JValue result2;
769 tmp->SetVReg(0, static_cast<int32_t>(i));
770 UnstartedCharacterToUpperCase(self, tmp, &result2, 0);
771 ASSERT_FALSE(self->IsExceptionPending());
772 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
773 if (c_upper) {
774 EXPECT_EQ(i, upper_result);
775 } else if (c_lower) {
776 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
777 upper_result);
778 } else {
779 EXPECT_EQ(i, upper_result);
780 }
781 }
782 }
783
784 // Check abort for other things. Can't test all.
785
786 PrepareForAborts();
787
788 for (uint32_t i = 128; i < 256; ++i) {
789 {
790 JValue result;
791 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700792 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700793 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700794 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700795 Runtime::Current()->ExitTransactionMode();
796 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700797 }
798 {
799 JValue result;
800 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700801 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700802 UnstartedCharacterToUpperCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700803 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700804 Runtime::Current()->ExitTransactionMode();
805 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700806 }
807 }
808 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
809 {
810 JValue result;
811 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700812 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700813 UnstartedCharacterToLowerCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700814 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700815 Runtime::Current()->ExitTransactionMode();
816 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700817 }
818 {
819 JValue result;
820 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700821 Runtime::Current()->EnterTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700822 UnstartedCharacterToUpperCase(self, tmp, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700823 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700824 Runtime::Current()->ExitTransactionMode();
825 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700826 }
827 }
828
829 ShadowFrame::DeleteDeoptimizedFrame(tmp);
830}
831
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700832TEST_F(UnstartedRuntimeTest, Sin) {
833 Thread* self = Thread::Current();
834 ScopedObjectAccess soa(self);
835
836 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
837
838 // Test an important value, PI/6. That's the one we see in practice.
839 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
840 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
841
842 JValue result;
843 UnstartedMathSin(self, tmp, &result, 0);
844
845 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
846 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
847
848 ShadowFrame::DeleteDeoptimizedFrame(tmp);
849}
850
851TEST_F(UnstartedRuntimeTest, Cos) {
852 Thread* self = Thread::Current();
853 ScopedObjectAccess soa(self);
854
855 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
856
857 // Test an important value, PI/6. That's the one we see in practice.
858 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
859 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
860
861 JValue result;
862 UnstartedMathCos(self, tmp, &result, 0);
863
864 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
865 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
866
867 ShadowFrame::DeleteDeoptimizedFrame(tmp);
868}
869
870TEST_F(UnstartedRuntimeTest, Pow) {
Andreas Gampeb6795152016-04-21 17:23:31 -0700871 // Valgrind seems to get this wrong, actually. Disable for valgrind.
872 if (RUNNING_ON_MEMORY_TOOL != 0 && kMemoryToolIsValgrind) {
873 return;
874 }
875
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700876 Thread* self = Thread::Current();
877 ScopedObjectAccess soa(self);
878
879 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
880
881 // Test an important pair.
882 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
883 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
884
885 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
886 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
887
888 JValue result;
889 UnstartedMathPow(self, tmp, &result, 0);
890
891 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
892 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
893
894 ShadowFrame::DeleteDeoptimizedFrame(tmp);
895}
896
Andreas Gampeae78c262017-02-01 20:40:44 -0800897TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
898 Thread* self = Thread::Current();
899 ScopedObjectAccess soa(self);
900
901 JValue result;
902 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
903
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100904 ObjPtr<mirror::Class> class_klass = mirror::Class::GetJavaLangClass();
Andreas Gampeae78c262017-02-01 20:40:44 -0800905 shadow_frame->SetVRegReference(0, class_klass);
906 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
907 EXPECT_EQ(result.GetZ(), 0);
908
909 jobject class_loader = LoadDex("Nested");
910 StackHandleScope<1> hs(soa.Self());
911 Handle<mirror::ClassLoader> loader(
912 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100913 ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
Andreas Gampeae78c262017-02-01 20:40:44 -0800914 ASSERT_TRUE(c != nullptr);
915 shadow_frame->SetVRegReference(0, c);
916 UnstartedClassIsAnonymousClass(self, shadow_frame, &result, 0);
917 EXPECT_EQ(result.GetZ(), 1);
918
919 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
920}
921
922TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
923 Thread* self = Thread::Current();
924 ScopedObjectAccess soa(self);
925
926 JValue result;
927 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
928
929 jobject class_loader = LoadDex("Nested");
930 StackHandleScope<4> hs(self);
931 Handle<mirror::ClassLoader> loader(
932 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
933
934 Handle<mirror::Class> nested_klass(hs.NewHandle(
935 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
936 Handle<mirror::Class> inner_klass(hs.NewHandle(
937 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
938 Handle<mirror::Class> anon_klass(hs.NewHandle(
939 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
940
941 shadow_frame->SetVRegReference(0, nested_klass.Get());
942 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
943 EXPECT_EQ(result.GetL(), nullptr);
944
945 shadow_frame->SetVRegReference(0, inner_klass.Get());
946 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
947 EXPECT_EQ(result.GetL(), nested_klass.Get());
948
949 shadow_frame->SetVRegReference(0, anon_klass.Get());
950 UnstartedClassGetDeclaringClass(self, shadow_frame, &result, 0);
951 EXPECT_EQ(result.GetL(), nullptr);
952
953 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
954}
955
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800956TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
957 Thread* self = Thread::Current();
958 ScopedObjectAccess soa(self);
959
960 JValue result;
961 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
962
963 StackHandleScope<1> hs(self);
964 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
965
966 // Positive test. See that We get something for float conversion.
967 {
968 Handle<mirror::Class> floating_decimal = hs.NewHandle(
969 class_linker->FindClass(self,
970 "Lsun/misc/FloatingDecimal;",
971 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800972 ASSERT_TRUE(floating_decimal != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800973 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
974
Vladimir Markoba118822017-06-12 15:41:56 +0100975 ArtMethod* caller_method = floating_decimal->FindClassMethod(
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800976 "getBinaryToASCIIBuffer",
977 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
978 class_linker->GetImagePointerSize());
979 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
980 ASSERT_TRUE(caller_method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100981 ASSERT_TRUE(caller_method->IsDirect());
982 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800983 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
984 shadow_frame->SetLink(caller_frame);
985
986 UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
987 EXPECT_TRUE(result.GetL() != nullptr);
988 EXPECT_FALSE(self->IsExceptionPending());
989
990 ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
991 }
992
993 // Negative test.
994 PrepareForAborts();
995
996 {
997 // Just use a method in Class.
998 ObjPtr<mirror::Class> class_class = mirror::Class::GetJavaLangClass();
999 ArtMethod* caller_method =
1000 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
1001 ShadowFrame* caller_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, caller_method, 0);
1002 shadow_frame->SetLink(caller_frame);
1003
Chang Xing16d1dd82017-07-20 17:56:26 -07001004 Runtime::Current()->EnterTransactionMode();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001005 UnstartedThreadLocalGet(self, shadow_frame, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001006 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001007 Runtime::Current()->ExitTransactionMode();
1008 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001009 self->ClearException();
1010
1011 ShadowFrame::DeleteDeoptimizedFrame(caller_frame);
1012 }
1013
1014 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1015}
1016
1017TEST_F(UnstartedRuntimeTest, FloatConversion) {
1018 Thread* self = Thread::Current();
1019 ScopedObjectAccess soa(self);
1020
1021 StackHandleScope<1> hs(self);
1022 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1023 Handle<mirror::Class> double_class = hs.NewHandle(
1024 class_linker->FindClass(self,
1025 "Ljava/lang/Double;",
1026 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001027 ASSERT_TRUE(double_class != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001028 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1029
Vladimir Markoba118822017-06-12 15:41:56 +01001030 ArtMethod* method = double_class->FindClassMethod("toString",
1031 "(D)Ljava/lang/String;",
1032 class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001033 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +01001034 ASSERT_TRUE(method->IsDirect());
1035 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001036
1037 // create instruction data for invoke-direct {v0, v1} of method with fake index
1038 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001039
1040 JValue result;
1041 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, method, 0);
1042 shadow_frame->SetVRegDouble(0, 1.23);
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001043 interpreter::DoCall<false, false>(method,
1044 self,
1045 *shadow_frame,
1046 Instruction::At(inst_data),
1047 inst_data[0],
1048 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001049 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001050 ASSERT_TRUE(string_result != nullptr);
1051
1052 std::string mod_utf = string_result->ToModifiedUtf8();
1053 EXPECT_EQ("1.23", mod_utf);
1054
1055 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1056}
1057
Andreas Gampebad529d2017-02-13 18:52:10 -08001058TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1059 Thread* self = Thread::Current();
1060 ScopedObjectAccess soa(self);
1061
1062 JValue result;
1063 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1064
1065 StackHandleScope<1> hs(self);
1066 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1067 Handle<mirror::Class> thread_class = hs.NewHandle(
1068 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1069 ASSERT_TRUE(thread_class.Get() != nullptr);
1070 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1071
1072 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1073 // be recreated at runtime).
1074 PrepareForAborts();
1075
1076 {
Chang Xing16d1dd82017-07-20 17:56:26 -07001077 Runtime::Current()->EnterTransactionMode();
Andreas Gampebad529d2017-02-13 18:52:10 -08001078 UnstartedThreadCurrentThread(self, shadow_frame, &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001079 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampebad529d2017-02-13 18:52:10 -08001080 Runtime::Current()->ExitTransactionMode();
1081 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampebad529d2017-02-13 18:52:10 -08001082 self->ClearException();
1083 }
1084
1085 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1086}
1087
1088TEST_F(UnstartedRuntimeTest, LogManager) {
1089 Thread* self = Thread::Current();
1090 ScopedObjectAccess soa(self);
1091
1092 StackHandleScope<1> hs(self);
1093 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1094 Handle<mirror::Class> log_manager_class = hs.NewHandle(
Andreas Gampe9486a162017-02-16 15:17:47 -08001095 class_linker->FindClass(self,
1096 "Ljava/util/logging/LogManager;",
1097 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampebad529d2017-02-13 18:52:10 -08001098 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1099 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1100}
1101
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001102class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1103 public:
1104 template <typename T>
1105 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1106 Thread* self = Thread::Current();
1107 ScopedObjectAccess soa(self);
1108
1109 // Ensure that Class is initialized.
1110 {
1111 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1112 StackHandleScope<1> hs(self);
1113 Handle<mirror::Class> h_class = hs.NewHandle(mirror::Class::GetJavaLangClass());
1114 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1115 }
1116
1117 // A selection of classes from different core classpath components.
1118 constexpr const char* kTestCases[] = {
1119 "java.net.CookieManager", // From libcore.
1120 "dalvik.system.ClassExt", // From libart.
1121 };
1122
1123 if (in_transaction) {
1124 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1125 // classes isn't transactional. Load them ahead of time.
1126 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1127 for (const char* name : kTestCases) {
1128 class_linker->FindClass(self,
1129 DotToDescriptor(name).c_str(),
1130 ScopedNullHandle<mirror::ClassLoader>());
1131 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1132 }
1133 }
1134
1135 if (!should_succeed) {
1136 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1137 // be recreated at runtime).
1138 PrepareForAborts();
1139 }
1140
1141 JValue result;
1142 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1143
1144 for (const char* name : kTestCases) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001145 ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001146 CHECK(name_string != nullptr);
1147
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001148 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001149 Runtime::Current()->EnterTransactionMode();
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001150 }
1151 CHECK(!self->IsExceptionPending());
1152
1153 runner(self, shadow_frame, name_string, &result);
1154
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001155 if (should_succeed) {
1156 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1157 CHECK(result.GetL() != nullptr) << name;
1158 } else {
1159 CHECK(self->IsExceptionPending()) << name;
1160 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001161 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001162 }
1163 self->ClearException();
1164 }
Chang Xing16d1dd82017-07-20 17:56:26 -07001165
1166 if (in_transaction) {
1167 Runtime::Current()->ExitTransactionMode();
1168 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001169 }
1170
1171 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1172 }
1173
1174 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1175 Thread* self = Thread::Current();
1176 StackHandleScope<2> hs(self);
1177 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1178
1179 {
1180 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1181
1182 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1183 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1184 class_linker->FindClass(self,
1185 "Ljava/lang/BootClassLoader;",
1186 ScopedNullHandle<mirror::ClassLoader>()));
1187 CHECK(boot_cp_class != nullptr);
1188 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1189
1190 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1191 CHECK(boot_cp != nullptr);
1192
Vladimir Markoba118822017-06-12 15:41:56 +01001193 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1194 "()V", class_linker->GetImagePointerSize());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001195 CHECK(boot_cp_init != nullptr);
1196
1197 JValue result;
1198 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, boot_cp_init, 0);
1199 shadow_frame->SetVRegReference(0, boot_cp.Get());
1200
1201 // create instruction data for invoke-direct {v0} of method with fake index
1202 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001203
1204 interpreter::DoCall<false, false>(boot_cp_init,
1205 self,
1206 *shadow_frame,
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001207 Instruction::At(inst_data),
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001208 inst_data[0],
1209 &result);
1210 CHECK(!self->IsExceptionPending());
1211
1212 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1213 }
1214
1215 return boot_cp.Get();
1216 }
1217};
1218
1219TEST_F(UnstartedClassForNameTest, ClassForName) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001220 auto runner = [](Thread* self,
1221 ShadowFrame* shadow_frame,
1222 ObjPtr<mirror::String> name,
1223 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001224 shadow_frame->SetVRegReference(0, name);
1225 UnstartedClassForName(self, shadow_frame, result, 0);
1226 };
1227 RunTest(runner, false, true);
1228}
1229
1230TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001231 auto runner = [](Thread* self,
1232 ShadowFrame* shadow_frame,
1233 ObjPtr<mirror::String> name,
1234 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001235 shadow_frame->SetVRegReference(0, name);
1236 shadow_frame->SetVReg(1, 0);
1237 shadow_frame->SetVRegReference(2, nullptr);
1238 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1239 };
1240 RunTest(runner, false, true);
1241}
1242
1243TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1244 Thread* self = Thread::Current();
1245 ScopedObjectAccess soa(self);
1246
1247 StackHandleScope<1> hs(self);
1248 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1249
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001250 auto runner = [&](Thread* th,
1251 ShadowFrame* shadow_frame,
1252 ObjPtr<mirror::String> name,
1253 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001254 shadow_frame->SetVRegReference(0, name);
1255 shadow_frame->SetVReg(1, 0);
1256 shadow_frame->SetVRegReference(2, boot_cp.Get());
1257 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1258 };
1259 RunTest(runner, false, true);
1260}
1261
1262TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1263 Thread* self = Thread::Current();
1264 ScopedObjectAccess soa(self);
1265
1266 StackHandleScope<1> hs(self);
1267 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1268
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001269 auto runner = [&](Thread* th,
1270 ShadowFrame* shadow_frame,
1271 ObjPtr<mirror::String> name,
1272 JValue* result)
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001273 REQUIRES_SHARED(Locks::mutator_lock_) {
1274 shadow_frame->SetVRegReference(0, name);
1275 shadow_frame->SetVReg(1, 0);
1276 shadow_frame->SetVRegReference(2, boot_cp.Get());
1277 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1278 };
1279 RunTest(runner, true, true);
1280}
1281
1282TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1283 Thread* self = Thread::Current();
1284 ScopedObjectAccess soa(self);
1285
1286 StackHandleScope<2> hs(self);
1287 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1288 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1289 ASSERT_TRUE(path_jobj != nullptr);
1290 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1291 self->DecodeJObject(path_jobj)->AsClassLoader());
1292
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001293 auto runner = [&](Thread* th,
1294 ShadowFrame* shadow_frame,
1295 ObjPtr<mirror::String> name,
1296 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001297 shadow_frame->SetVRegReference(0, name);
1298 shadow_frame->SetVReg(1, 0);
1299 shadow_frame->SetVRegReference(2, path_cp.Get());
1300 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1301 };
1302 RunTest(runner, true, false);
1303}
1304
Andreas Gampe9486a162017-02-16 15:17:47 -08001305TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1306 Thread* self = Thread::Current();
1307 ScopedObjectAccess soa(self);
1308
1309 StackHandleScope<1> hs(self);
1310 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1311 Handle<mirror::Class> list_class = hs.NewHandle(
1312 class_linker->FindClass(self,
1313 "Ljava/util/List;",
1314 ScopedNullHandle<mirror::ClassLoader>()));
1315 ASSERT_TRUE(list_class.Get() != nullptr);
1316 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1317
1318 JValue result;
1319 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1320
1321 shadow_frame->SetVRegReference(0, list_class.Get());
1322 UnstartedClassGetSignatureAnnotation(self, shadow_frame, &result, 0);
1323 ASSERT_TRUE(result.GetL() != nullptr);
1324 ASSERT_FALSE(self->IsExceptionPending());
1325
1326 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1327
1328 ASSERT_TRUE(result.GetL()->IsObjectArray());
1329 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1330 result.GetL()->AsObjectArray<mirror::Object>();
1331 std::ostringstream oss;
1332 for (int32_t i = 0; i != array->GetLength(); ++i) {
1333 ObjPtr<mirror::Object> elem = array->Get(i);
1334 ASSERT_TRUE(elem != nullptr);
1335 ASSERT_TRUE(elem->IsString());
1336 oss << elem->AsString()->ToModifiedUtf8();
1337 }
1338 std::string output_string = oss.str();
1339 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1340}
1341
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001342TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1343 Thread* self = Thread::Current();
1344 ScopedObjectAccess soa(self);
1345
1346 StackHandleScope<4> hs(self);
1347 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1348
1349 // Get Throwable.
1350 Handle<mirror::Class> throw_class = hs.NewHandle(mirror::Throwable::GetJavaLangThrowable());
1351 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1352
1353 // Get an input object.
1354 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1355
1356 // Find the constructor.
Vladimir Markoba118822017-06-12 15:41:56 +01001357 ArtMethod* throw_cons = throw_class->FindConstructor(
1358 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001359 ASSERT_TRUE(throw_cons != nullptr);
Chang Xingfef27c22017-07-11 09:57:44 -07001360 Handle<mirror::Constructor> cons;
1361 if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1362 cons = hs.NewHandle(
1363 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1364 ASSERT_TRUE(cons != nullptr);
1365 } else {
1366 cons = hs.NewHandle(
1367 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1368 ASSERT_TRUE(cons != nullptr);
1369 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001370
1371 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
Andreas Gampec6ea7d02017-02-01 16:46:28 -08001372 mirror::ObjectArray<mirror::Object>::Alloc(
1373 self, class_linker_->GetClassRoot(ClassLinker::ClassRoot::kObjectArrayClass), 1));
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001374 ASSERT_TRUE(args != nullptr);
1375 args->Set(0, input.Get());
1376
1377 // OK, we're ready now.
1378 JValue result;
1379 ShadowFrame* shadow_frame = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1380 shadow_frame->SetVRegReference(0, cons.Get());
1381 shadow_frame->SetVRegReference(1, args.Get());
1382 UnstartedConstructorNewInstance0(self, shadow_frame, &result, 0);
1383
1384 ASSERT_TRUE(result.GetL() != nullptr);
1385 ASSERT_FALSE(self->IsExceptionPending());
1386
1387 // Should be a new object.
1388 ASSERT_NE(result.GetL(), input.Get());
1389 // Should be a String.
1390 ASSERT_EQ(mirror::Throwable::GetJavaLangThrowable(), result.GetL()->GetClass());
1391 // Should have the right string.
1392 ObjPtr<mirror::String> result_msg =
1393 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001394 EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001395
1396 ShadowFrame::DeleteDeoptimizedFrame(shadow_frame);
1397}
1398
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001399TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1400 Thread* self = Thread::Current();
1401 ScopedObjectAccess soa(self);
1402 ShadowFrame* tmp = ShadowFrame::CreateDeoptimizedFrame(10, nullptr, nullptr, 0);
1403
1404 JValue result;
1405 UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1406
1407 EXPECT_EQ(0, result.GetI());
1408 ASSERT_FALSE(self->IsExceptionPending());
1409
1410 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001411 tmp->SetVRegReference(0, str);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001412 UnstartedSystemIdentityHashCode(self, tmp, &result, 0);
1413 EXPECT_NE(0, result.GetI());
1414 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1415 ASSERT_FALSE(self->IsExceptionPending());
1416
1417 ShadowFrame::DeleteDeoptimizedFrame(tmp);
1418}
1419
Andreas Gampe799681b2015-05-15 19:24:12 -07001420} // namespace interpreter
1421} // namespace art