blob: 727c5f3f22f39e3988c48c00e6318b7ee6cb6d04 [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 Gampe8e0f0432018-10-24 13:38:03 -070033#include "mirror/array-alloc-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070034#include "mirror/class_loader.h"
Andreas Gampe9486a162017-02-16 15:17:47 -080035#include "mirror/object-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070036#include "mirror/object_array-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070037#include "mirror/string-inl.h"
38#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070039#include "scoped_thread_state_change-inl.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010040#include "shadow_frame-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070041#include "thread.h"
Andreas Gampe8ce9c302016-04-15 21:24:28 -070042#include "transaction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070043
44namespace art {
45namespace interpreter {
46
Andreas Gampedbf54032018-06-18 14:47:01 -070047// Deleter to be used with ShadowFrame::CreateDeoptimizedFrame objects.
48struct DeoptShadowFrameDelete {
49 // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
50 void operator()(ShadowFrame* ptr) const {
51 if (ptr != nullptr) {
52 ShadowFrame::DeleteDeoptimizedFrame(ptr);
53 }
54 }
55};
56// Alias for std::unique_ptr<> that uses the above deleter.
57using UniqueDeoptShadowFramePtr = std::unique_ptr<ShadowFrame, DeoptShadowFrameDelete>;
58
Andreas Gampe799681b2015-05-15 19:24:12 -070059class UnstartedRuntimeTest : public CommonRuntimeTest {
60 protected:
61 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
62 // test friends.
63
64 // Methods that intercept available libcore implementations.
65#define UNSTARTED_DIRECT(Name, SigIgnored) \
66 static void Unstarted ## Name(Thread* self, \
67 ShadowFrame* shadow_frame, \
68 JValue* result, \
69 size_t arg_offset) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070070 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070071 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
72 }
73#include "unstarted_runtime_list.h"
74 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
75#undef UNSTARTED_RUNTIME_DIRECT_LIST
76#undef UNSTARTED_RUNTIME_JNI_LIST
77#undef UNSTARTED_DIRECT
78
79 // Methods that are native.
Mathieu Chartiere401d142015-04-22 13:56:20 -070080#define UNSTARTED_JNI(Name, SigIgnored) \
Andreas Gampe799681b2015-05-15 19:24:12 -070081 static void UnstartedJNI ## Name(Thread* self, \
Mathieu Chartiere401d142015-04-22 13:56:20 -070082 ArtMethod* method, \
Andreas Gampe799681b2015-05-15 19:24:12 -070083 mirror::Object* receiver, \
84 uint32_t* args, \
85 JValue* result) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070086 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070087 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
88 }
89#include "unstarted_runtime_list.h"
90 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
91#undef UNSTARTED_RUNTIME_DIRECT_LIST
92#undef UNSTARTED_RUNTIME_JNI_LIST
93#undef UNSTARTED_JNI
Andreas Gampe85a098a2016-03-31 13:30:53 -070094
Andreas Gampedbf54032018-06-18 14:47:01 -070095 UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs,
96 ShadowFrame* link,
97 ArtMethod* method,
98 uint32_t dex_pc) {
99 return UniqueDeoptShadowFramePtr(
100 ShadowFrame::CreateDeoptimizedFrame(num_vregs, link, method, dex_pc));
101 }
102
Andreas Gampe85a098a2016-03-31 13:30:53 -0700103 // Helpers for ArrayCopy.
104 //
105 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
106 // of three everywhere. That is enough to test all cases.
107
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100108 static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
Andreas Gampe85a098a2016-03-31 13:30:53 -0700109 Thread* self,
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700110 ObjPtr<mirror::Class> component_type,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700111 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700112 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700113 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700114 ObjPtr<mirror::Class> array_type =
Vladimir Markobcf17522018-06-01 13:14:32 +0100115 runtime->GetClassLinker()->FindArrayClass(self, component_type);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700116 CHECK(array_type != nullptr);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700117 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
Andreas Gampe85a098a2016-03-31 13:30:53 -0700118 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
119 CHECK(result != nullptr);
120 for (size_t i = 0; i < 3; ++i) {
121 result->Set(static_cast<int32_t>(i), data.GetReference(i));
122 CHECK(!self->IsExceptionPending());
123 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100124 return result;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700125 }
126
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100127 static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700128 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700129 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700130 CHECK_EQ(array->GetLength(), 3);
131 CHECK_EQ(data.NumberOfReferences(), 3U);
132 for (size_t i = 0; i < 3; ++i) {
133 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
134 }
135 }
136
137 void RunArrayCopy(Thread* self,
138 ShadowFrame* tmp,
139 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100140 ObjPtr<mirror::ObjectArray<mirror::Object>> src,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700141 int32_t src_pos,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100142 ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700143 int32_t dst_pos,
144 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700145 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700146 JValue result;
147 tmp->SetVRegReference(0, src);
148 tmp->SetVReg(1, src_pos);
149 tmp->SetVRegReference(2, dst);
150 tmp->SetVReg(3, dst_pos);
151 tmp->SetVReg(4, length);
152 UnstartedSystemArraycopy(self, tmp, &result, 0);
153 bool exception_pending = self->IsExceptionPending();
154 EXPECT_EQ(exception_pending, expect_exception);
155 if (exception_pending) {
156 self->ClearException();
157 }
158 }
159
160 void RunArrayCopy(Thread* self,
161 ShadowFrame* tmp,
162 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100163 ObjPtr<mirror::Class> src_component_class,
164 ObjPtr<mirror::Class> dst_component_class,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700165 const StackHandleScope<3>& src_data,
166 int32_t src_pos,
167 const StackHandleScope<3>& dst_data,
168 int32_t dst_pos,
169 int32_t length,
170 const StackHandleScope<3>& expected_result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700171 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700172 StackHandleScope<3> hs_misc(self);
173 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
174
175 Handle<mirror::ObjectArray<mirror::Object>> src_handle(
176 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
177
178 Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
179 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
180
181 RunArrayCopy(self,
182 tmp,
183 expect_exception,
184 src_handle.Get(),
185 src_pos,
186 dst_handle.Get(),
187 dst_pos,
188 length);
189 CheckObjectArray(dst_handle.Get(), expected_result);
190 }
Andreas Gampe89e3b482016-04-12 18:07:36 -0700191
192 void TestCeilFloor(bool ceil,
193 Thread* self,
194 ShadowFrame* tmp,
195 double const test_pairs[][2],
196 size_t num_pairs)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700197 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700198 for (size_t i = 0; i < num_pairs; ++i) {
199 tmp->SetVRegDouble(0, test_pairs[i][0]);
200
201 JValue result;
202 if (ceil) {
203 UnstartedMathCeil(self, tmp, &result, 0);
204 } else {
205 UnstartedMathFloor(self, tmp, &result, 0);
206 }
207
208 ASSERT_FALSE(self->IsExceptionPending());
209
210 // We want precise results.
211 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
212 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
213 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
214 }
215 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700216
217 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
218 // loading code doesn't work under transactions.
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700219 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100220 ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700221 Thread::Current(),
222 Transaction::kAbortExceptionSignature,
223 ScopedNullHandle<mirror::ClassLoader>());
224 CHECK(result != nullptr);
225 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700226};
227
228TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
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;
Andreas Gampedbf54032018-06-18 14:47:01 -0700237 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700238
239 for (int32_t i = 0; i < kBaseLen; ++i) {
240 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
241
Andreas Gampedbf54032018-06-18 14:47:01 -0700242 UnstartedMemoryPeekByte(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700243
244 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
245 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700246}
247
248TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
249 Thread* self = Thread::Current();
250
251 ScopedObjectAccess soa(self);
252 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
253 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
254 const uint8_t* base_ptr = base_array;
255
256 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700257 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700258
259 int32_t adjusted_length = kBaseLen - sizeof(int16_t);
260 for (int32_t i = 0; i < adjusted_length; ++i) {
261 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
262
Andreas Gampedbf54032018-06-18 14:47:01 -0700263 UnstartedMemoryPeekShort(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700264
Andreas Gampec55bb392018-09-21 00:02:02 +0000265 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700266 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
267 EXPECT_EQ(result.GetS(), *short_ptr);
268 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700269}
270
271TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
272 Thread* self = Thread::Current();
273
274 ScopedObjectAccess soa(self);
275 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
276 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
277 const uint8_t* base_ptr = base_array;
278
279 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700280 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700281
282 int32_t adjusted_length = kBaseLen - sizeof(int32_t);
283 for (int32_t i = 0; i < adjusted_length; ++i) {
284 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
285
Andreas Gampedbf54032018-06-18 14:47:01 -0700286 UnstartedMemoryPeekInt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700287
Andreas Gampec55bb392018-09-21 00:02:02 +0000288 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700289 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
290 EXPECT_EQ(result.GetI(), *int_ptr);
291 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700292}
293
294TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
295 Thread* self = Thread::Current();
296
297 ScopedObjectAccess soa(self);
298 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
299 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
300 const uint8_t* base_ptr = base_array;
301
302 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700303 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700304
305 int32_t adjusted_length = kBaseLen - sizeof(int64_t);
306 for (int32_t i = 0; i < adjusted_length; ++i) {
307 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
308
Andreas Gampedbf54032018-06-18 14:47:01 -0700309 UnstartedMemoryPeekLong(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700310
Andreas Gampec55bb392018-09-21 00:02:02 +0000311 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700312 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
313 EXPECT_EQ(result.GetJ(), *long_ptr);
314 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700315}
316
317TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
318 Thread* self = Thread::Current();
319
320 ScopedObjectAccess soa(self);
321 StackHandleScope<2> hs(self);
322 // TODO: Actual UTF.
323 constexpr const char base_string[] = "abcdefghijklmnop";
324 Handle<mirror::String> h_test_string(hs.NewHandle(
325 mirror::String::AllocFromModifiedUtf8(self, base_string)));
326 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
327 Handle<mirror::CharArray> h_char_array(hs.NewHandle(
328 mirror::CharArray::Alloc(self, kBaseLen)));
329 // A buffer so we can make sure we only modify the elements targetted.
330 uint16_t buf[kBaseLen];
331
332 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700333 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700334
335 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
336 for (int32_t count = 0; count <= kBaseLen; ++count) {
337 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
338 // Only do it when in bounds.
339 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
340 tmp->SetVRegReference(0, h_test_string.Get());
341 tmp->SetVReg(1, start_index);
342 tmp->SetVReg(2, count);
343 tmp->SetVRegReference(3, h_char_array.Get());
344 tmp->SetVReg(3, trg_offset);
345
346 // Copy the char_array into buf.
347 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
348
Andreas Gampedbf54032018-06-18 14:47:01 -0700349 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700350
351 uint16_t* data = h_char_array->GetData();
352
353 bool success = true;
354
355 // First segment should be unchanged.
356 for (int32_t i = 0; i < trg_offset; ++i) {
357 success = success && (data[i] == buf[i]);
358 }
359 // Second segment should be a copy.
360 for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
361 success = success && (data[i] == buf[i - trg_offset + start_index]);
362 }
363 // Third segment should be unchanged.
364 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
365 success = success && (data[i] == buf[i]);
366 }
367
368 EXPECT_TRUE(success);
369 }
370 }
371 }
372 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700373}
374
375TEST_F(UnstartedRuntimeTest, StringCharAt) {
376 Thread* self = Thread::Current();
377
378 ScopedObjectAccess soa(self);
379 // TODO: Actual UTF.
380 constexpr const char* base_string = "abcdefghijklmnop";
381 int32_t base_len = static_cast<int32_t>(strlen(base_string));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100382 ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
Andreas Gampe799681b2015-05-15 19:24:12 -0700383
384 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700385 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700386
387 for (int32_t i = 0; i < base_len; ++i) {
388 tmp->SetVRegReference(0, test_string);
389 tmp->SetVReg(1, i);
390
Andreas Gampedbf54032018-06-18 14:47:01 -0700391 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700392
393 EXPECT_EQ(result.GetI(), base_string[i]);
394 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700395}
396
Jeff Hao400ce002015-05-29 10:53:17 -0700397TEST_F(UnstartedRuntimeTest, StringInit) {
398 Thread* self = Thread::Current();
399 ScopedObjectAccess soa(self);
Vladimir Markoacb906d2018-05-30 10:23:49 +0100400 ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
Chang Xingfef27c22017-07-11 09:57:44 -0700401 ArtMethod* method =
Vladimir Markoba118822017-06-12 15:41:56 +0100402 klass->FindConstructor("(Ljava/lang/String;)V",
403 Runtime::Current()->GetClassLinker()->GetImagePointerSize());
404 ASSERT_TRUE(method != nullptr);
Jeff Hao400ce002015-05-29 10:53:17 -0700405
406 // create instruction data for invoke-direct {v0, v1} of method with fake index
407 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Jeff Hao400ce002015-05-29 10:53:17 -0700408
409 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700410 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
Jeff Hao400ce002015-05-29 10:53:17 -0700411 const char* base_string = "hello_world";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100412 StackHandleScope<2> hs(self);
413 Handle<mirror::String> string_arg =
414 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
415 Handle<mirror::String> reference_empty_string =
416 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
417 shadow_frame->SetVRegReference(0, reference_empty_string.Get());
418 shadow_frame->SetVRegReference(1, string_arg.Get());
Jeff Hao400ce002015-05-29 10:53:17 -0700419
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700420 interpreter::DoCall<false, false>(method,
421 self,
422 *shadow_frame,
423 Instruction::At(inst_data),
424 inst_data[0],
425 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100426 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Jeff Hao400ce002015-05-29 10:53:17 -0700427 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700428
429 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
430 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
431 string_arg->GetLength() * sizeof(uint8_t)), 0);
432 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
433 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
434 string_arg->GetLength() * sizeof(uint16_t)), 0);
435 } else {
436 bool equal = true;
437 for (int i = 0; i < string_arg->GetLength(); ++i) {
438 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
439 equal = false;
440 break;
441 }
442 }
443 EXPECT_EQ(equal, true);
444 }
Jeff Hao400ce002015-05-29 10:53:17 -0700445}
446
Andreas Gampe85a098a2016-03-31 13:30:53 -0700447// Tests the exceptions that should be checked before modifying the destination.
448// (Doesn't check the object vs primitive case ATM.)
449TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
450 Thread* self = Thread::Current();
451 ScopedObjectAccess soa(self);
452 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700453 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700454
455 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
456 // allocate.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100457 StackHandleScope<3> hs_misc(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100458 Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700459
460 StackHandleScope<3> hs_data(self);
461 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
462 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
463 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
464
465 Handle<mirror::ObjectArray<mirror::Object>> array(
466 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
467
Andreas Gampedbf54032018-06-18 14:47:01 -0700468 RunArrayCopy(self, tmp.get(), true, array.Get(), -1, array.Get(), 0, 0);
469 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), -1, 0);
470 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, -1);
471 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, 4);
472 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 1, 3);
473 RunArrayCopy(self, tmp.get(), true, array.Get(), 1, array.Get(), 0, 3);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700474
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100475 Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
476 hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
Andreas Gampedbf54032018-06-18 14:47:01 -0700477 RunArrayCopy(self, tmp.get(), true, class_as_array.Get(), 0, array.Get(), 0, 0);
478 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, class_as_array.Get(), 0, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700479}
480
481TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
482 Thread* self = Thread::Current();
483 ScopedObjectAccess soa(self);
484 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700485 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700486
487 StackHandleScope<1> hs_object(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100488 Handle<mirror::Class> object_class(hs_object.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700489
490 // Simple test:
491 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
492 {
493 StackHandleScope<3> hs_src(self);
494 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
495 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
496 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
497
498 StackHandleScope<3> hs_dst(self);
499 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
500 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
501 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
502
503 StackHandleScope<3> hs_expected(self);
504 hs_expected.NewHandle(hs_dst.GetReference(0));
505 hs_expected.NewHandle(hs_dst.GetReference(1));
506 hs_expected.NewHandle(hs_src.GetReference(1));
507
508 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700509 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700510 false,
511 object_class.Get(),
512 object_class.Get(),
513 hs_src,
514 1,
515 hs_dst,
516 2,
517 1,
518 hs_expected);
519 }
520
521 // Simple test:
522 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
523 {
524 StackHandleScope<3> hs_src(self);
525 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
526 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
527 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
528
529 StackHandleScope<3> hs_dst(self);
530 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
531 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
532 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
533
534 StackHandleScope<3> hs_expected(self);
535 hs_expected.NewHandle(hs_dst.GetReference(0));
536 hs_expected.NewHandle(hs_src.GetReference(1));
537 hs_expected.NewHandle(hs_dst.GetReference(2));
538
539 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700540 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700541 false,
542 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100543 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700544 hs_src,
545 1,
546 hs_dst,
547 1,
548 1,
549 hs_expected);
550 }
551
552 // Simple test:
553 // [1,*,3] into [4,5,6] = [1,5,6] + exc
554 {
555 StackHandleScope<3> hs_src(self);
556 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
Vladimir Markoacb906d2018-05-30 10:23:49 +0100557 hs_src.NewHandle(GetClassRoot<mirror::String>());
Andreas Gampe85a098a2016-03-31 13:30:53 -0700558 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
559
560 StackHandleScope<3> hs_dst(self);
561 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
562 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
563 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
564
565 StackHandleScope<3> hs_expected(self);
566 hs_expected.NewHandle(hs_src.GetReference(0));
567 hs_expected.NewHandle(hs_dst.GetReference(1));
568 hs_expected.NewHandle(hs_dst.GetReference(2));
569
570 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700571 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700572 true,
573 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100574 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700575 hs_src,
576 0,
577 hs_dst,
578 0,
579 3,
580 hs_expected);
581 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700582}
583
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700584TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
585 Thread* self = Thread::Current();
586 ScopedObjectAccess soa(self);
587
Andreas Gampedbf54032018-06-18 14:47:01 -0700588 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700589
590 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
591 // suffixes).
592 constexpr const char* test_string = "-2147483646";
593 constexpr int32_t test_values[] = {
594 6,
595 46,
596 646,
597 3646,
598 83646,
599 483646,
600 7483646,
601 47483646,
602 147483646,
603 2147483646,
604 -2147483646
605 };
606
607 static_assert(arraysize(test_values) == 11U, "test_values");
608 CHECK_EQ(strlen(test_string), 11U);
609
610 for (size_t i = 0; i <= 10; ++i) {
611 const char* test_value = &test_string[10 - i];
612
613 StackHandleScope<1> hs_str(self);
614 Handle<mirror::String> h_str(
615 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
616 ASSERT_NE(h_str.Get(), nullptr);
617 ASSERT_FALSE(self->IsExceptionPending());
618
619 tmp->SetVRegReference(0, h_str.Get());
620
621 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700622 UnstartedIntegerParseInt(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700623
624 ASSERT_FALSE(self->IsExceptionPending());
625 EXPECT_EQ(result.GetI(), test_values[i]);
626 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700627}
628
629// Right now the same as Integer.Parse
630TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
631 Thread* self = Thread::Current();
632 ScopedObjectAccess soa(self);
633
Andreas Gampedbf54032018-06-18 14:47:01 -0700634 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700635
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;
Andreas Gampedbf54032018-06-18 14:47:01 -0700668 UnstartedLongParseLong(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700669
670 ASSERT_FALSE(self->IsExceptionPending());
671 EXPECT_EQ(result.GetJ(), test_values[i]);
672 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700673}
674
Andreas Gampe89e3b482016-04-12 18:07:36 -0700675TEST_F(UnstartedRuntimeTest, Ceil) {
676 Thread* self = Thread::Current();
677 ScopedObjectAccess soa(self);
678
Andreas Gampedbf54032018-06-18 14:47:01 -0700679 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700680
681 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
682 constexpr double inf = std::numeric_limits<double>::infinity();
683 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
684 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
685 constexpr double test_pairs[][2] = {
686 { -0.0, -0.0 },
687 { 0.0, 0.0 },
688 { -0.5, -0.0 },
689 { -1.0, -1.0 },
690 { 0.5, 1.0 },
691 { 1.0, 1.0 },
692 { nan, nan },
693 { inf, inf },
694 { -inf, -inf },
695 { ld1, ld1 },
696 { ld2, ld2 }
697 };
698
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700699 TestCeilFloor(/* ceil= */ true, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700700}
701
702TEST_F(UnstartedRuntimeTest, Floor) {
703 Thread* self = Thread::Current();
704 ScopedObjectAccess soa(self);
705
Andreas Gampedbf54032018-06-18 14:47:01 -0700706 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700707
708 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
709 constexpr double inf = std::numeric_limits<double>::infinity();
710 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
711 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
712 constexpr double test_pairs[][2] = {
713 { -0.0, -0.0 },
714 { 0.0, 0.0 },
715 { -0.5, -1.0 },
716 { -1.0, -1.0 },
717 { 0.5, 0.0 },
718 { 1.0, 1.0 },
719 { nan, nan },
720 { inf, inf },
721 { -inf, -inf },
722 { ld1, ld1 },
723 { ld2, ld2 }
724 };
725
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700726 TestCeilFloor(/* ceil= */ false, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700727}
728
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700729TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
730 Thread* self = Thread::Current();
731 ScopedObjectAccess soa(self);
732
Andreas Gampedbf54032018-06-18 14:47:01 -0700733 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700734
735 std::locale c_locale("C");
736
737 // Check ASCII.
738 for (uint32_t i = 0; i < 128; ++i) {
739 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
740 bool c_lower = std::islower(static_cast<char>(i), c_locale);
741 EXPECT_FALSE(c_upper && c_lower) << i;
742
743 // Check toLowerCase.
744 {
745 JValue result;
746 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700747 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700748 ASSERT_FALSE(self->IsExceptionPending());
749 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
750 if (c_lower) {
751 EXPECT_EQ(i, lower_result);
752 } else if (c_upper) {
753 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
754 lower_result);
755 } else {
756 EXPECT_EQ(i, lower_result);
757 }
758 }
759
760 // Check toUpperCase.
761 {
762 JValue result2;
763 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700764 UnstartedCharacterToUpperCase(self, tmp.get(), &result2, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700765 ASSERT_FALSE(self->IsExceptionPending());
766 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
767 if (c_upper) {
768 EXPECT_EQ(i, upper_result);
769 } else if (c_lower) {
770 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
771 upper_result);
772 } else {
773 EXPECT_EQ(i, upper_result);
774 }
775 }
776 }
777
778 // Check abort for other things. Can't test all.
779
780 PrepareForAborts();
781
782 for (uint32_t i = 128; i < 256; ++i) {
783 {
784 JValue result;
785 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700786 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700787 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700788 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700789 Runtime::Current()->ExitTransactionMode();
790 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700791 }
792 {
793 JValue result;
794 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700795 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700796 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700797 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700798 Runtime::Current()->ExitTransactionMode();
799 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700800 }
801 }
802 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
803 {
804 JValue result;
805 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700806 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700807 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700808 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700809 Runtime::Current()->ExitTransactionMode();
810 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700811 }
812 {
813 JValue result;
814 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700815 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700816 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700817 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700818 Runtime::Current()->ExitTransactionMode();
819 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700820 }
821 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700822}
823
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700824TEST_F(UnstartedRuntimeTest, Sin) {
825 Thread* self = Thread::Current();
826 ScopedObjectAccess soa(self);
827
Andreas Gampedbf54032018-06-18 14:47:01 -0700828 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700829
830 // Test an important value, PI/6. That's the one we see in practice.
831 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
832 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
833
834 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700835 UnstartedMathSin(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700836
837 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
838 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700839}
840
841TEST_F(UnstartedRuntimeTest, Cos) {
842 Thread* self = Thread::Current();
843 ScopedObjectAccess soa(self);
844
Andreas Gampedbf54032018-06-18 14:47:01 -0700845 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700846
847 // Test an important value, PI/6. That's the one we see in practice.
848 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
849 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
850
851 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700852 UnstartedMathCos(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700853
854 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
855 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700856}
857
858TEST_F(UnstartedRuntimeTest, Pow) {
859 Thread* self = Thread::Current();
860 ScopedObjectAccess soa(self);
861
Andreas Gampedbf54032018-06-18 14:47:01 -0700862 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700863
864 // Test an important pair.
865 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
866 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
867
868 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
869 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
870
871 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700872 UnstartedMathPow(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700873
874 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
875 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700876}
877
Andreas Gampeae78c262017-02-01 20:40:44 -0800878TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
879 Thread* self = Thread::Current();
880 ScopedObjectAccess soa(self);
881
882 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700883 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800884
Vladimir Marko317892b2018-05-31 11:11:32 +0100885 ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
Andreas Gampeae78c262017-02-01 20:40:44 -0800886 shadow_frame->SetVRegReference(0, class_klass);
Andreas Gampedbf54032018-06-18 14:47:01 -0700887 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800888 EXPECT_EQ(result.GetZ(), 0);
889
890 jobject class_loader = LoadDex("Nested");
891 StackHandleScope<1> hs(soa.Self());
892 Handle<mirror::ClassLoader> loader(
893 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100894 ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
Andreas Gampeae78c262017-02-01 20:40:44 -0800895 ASSERT_TRUE(c != nullptr);
896 shadow_frame->SetVRegReference(0, c);
Andreas Gampedbf54032018-06-18 14:47:01 -0700897 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800898 EXPECT_EQ(result.GetZ(), 1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800899}
900
901TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
902 Thread* self = Thread::Current();
903 ScopedObjectAccess soa(self);
904
905 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700906 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800907
908 jobject class_loader = LoadDex("Nested");
909 StackHandleScope<4> hs(self);
910 Handle<mirror::ClassLoader> loader(
911 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
912
913 Handle<mirror::Class> nested_klass(hs.NewHandle(
914 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
915 Handle<mirror::Class> inner_klass(hs.NewHandle(
916 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
917 Handle<mirror::Class> anon_klass(hs.NewHandle(
918 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
919
920 shadow_frame->SetVRegReference(0, nested_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700921 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800922 EXPECT_EQ(result.GetL(), nullptr);
923
924 shadow_frame->SetVRegReference(0, inner_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700925 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800926 EXPECT_EQ(result.GetL(), nested_klass.Get());
927
928 shadow_frame->SetVRegReference(0, anon_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700929 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800930 EXPECT_EQ(result.GetL(), nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800931}
932
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800933TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
934 Thread* self = Thread::Current();
935 ScopedObjectAccess soa(self);
936
937 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700938 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800939
940 StackHandleScope<1> hs(self);
941 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
942
943 // Positive test. See that We get something for float conversion.
944 {
945 Handle<mirror::Class> floating_decimal = hs.NewHandle(
946 class_linker->FindClass(self,
947 "Lsun/misc/FloatingDecimal;",
948 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800949 ASSERT_TRUE(floating_decimal != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800950 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
951
Vladimir Markoba118822017-06-12 15:41:56 +0100952 ArtMethod* caller_method = floating_decimal->FindClassMethod(
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800953 "getBinaryToASCIIBuffer",
954 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
955 class_linker->GetImagePointerSize());
956 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
957 ASSERT_TRUE(caller_method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100958 ASSERT_TRUE(caller_method->IsDirect());
959 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700960 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
961 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800962
Andreas Gampedbf54032018-06-18 14:47:01 -0700963 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800964 EXPECT_TRUE(result.GetL() != nullptr);
965 EXPECT_FALSE(self->IsExceptionPending());
966
Andreas Gampedbf54032018-06-18 14:47:01 -0700967 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800968 }
969
970 // Negative test.
971 PrepareForAborts();
972
973 {
974 // Just use a method in Class.
Vladimir Marko317892b2018-05-31 11:11:32 +0100975 ObjPtr<mirror::Class> class_class = GetClassRoot<mirror::Class>();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800976 ArtMethod* caller_method =
977 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
Andreas Gampedbf54032018-06-18 14:47:01 -0700978 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
979 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800980
Chang Xing16d1dd82017-07-20 17:56:26 -0700981 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700982 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700983 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800984 Runtime::Current()->ExitTransactionMode();
985 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800986 self->ClearException();
987
Andreas Gampedbf54032018-06-18 14:47:01 -0700988 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800989 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800990}
991
992TEST_F(UnstartedRuntimeTest, FloatConversion) {
993 Thread* self = Thread::Current();
994 ScopedObjectAccess soa(self);
995
996 StackHandleScope<1> hs(self);
997 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
998 Handle<mirror::Class> double_class = hs.NewHandle(
999 class_linker->FindClass(self,
1000 "Ljava/lang/Double;",
1001 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001002 ASSERT_TRUE(double_class != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001003 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1004
Vladimir Markoba118822017-06-12 15:41:56 +01001005 ArtMethod* method = double_class->FindClassMethod("toString",
1006 "(D)Ljava/lang/String;",
1007 class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001008 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +01001009 ASSERT_TRUE(method->IsDirect());
1010 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001011
1012 // create instruction data for invoke-direct {v0, v1} of method with fake index
1013 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001014
1015 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001016 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
1017
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001018 shadow_frame->SetVRegDouble(0, 1.23);
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001019 interpreter::DoCall<false, false>(method,
1020 self,
1021 *shadow_frame,
1022 Instruction::At(inst_data),
1023 inst_data[0],
1024 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001025 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001026 ASSERT_TRUE(string_result != nullptr);
1027
1028 std::string mod_utf = string_result->ToModifiedUtf8();
1029 EXPECT_EQ("1.23", mod_utf);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001030}
1031
Andreas Gampebad529d2017-02-13 18:52:10 -08001032TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1033 Thread* self = Thread::Current();
1034 ScopedObjectAccess soa(self);
1035
1036 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001037 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampebad529d2017-02-13 18:52:10 -08001038
1039 StackHandleScope<1> hs(self);
1040 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1041 Handle<mirror::Class> thread_class = hs.NewHandle(
1042 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1043 ASSERT_TRUE(thread_class.Get() != nullptr);
1044 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1045
1046 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1047 // be recreated at runtime).
1048 PrepareForAborts();
1049
1050 {
Chang Xing16d1dd82017-07-20 17:56:26 -07001051 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -07001052 UnstartedThreadCurrentThread(self, shadow_frame.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001053 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampebad529d2017-02-13 18:52:10 -08001054 Runtime::Current()->ExitTransactionMode();
1055 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampebad529d2017-02-13 18:52:10 -08001056 self->ClearException();
1057 }
Andreas Gampebad529d2017-02-13 18:52:10 -08001058}
1059
1060TEST_F(UnstartedRuntimeTest, LogManager) {
1061 Thread* self = Thread::Current();
1062 ScopedObjectAccess soa(self);
1063
1064 StackHandleScope<1> hs(self);
1065 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1066 Handle<mirror::Class> log_manager_class = hs.NewHandle(
Andreas Gampe9486a162017-02-16 15:17:47 -08001067 class_linker->FindClass(self,
1068 "Ljava/util/logging/LogManager;",
1069 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampebad529d2017-02-13 18:52:10 -08001070 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1071 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1072}
1073
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001074class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1075 public:
1076 template <typename T>
1077 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1078 Thread* self = Thread::Current();
1079 ScopedObjectAccess soa(self);
1080
1081 // Ensure that Class is initialized.
1082 {
1083 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1084 StackHandleScope<1> hs(self);
Vladimir Marko317892b2018-05-31 11:11:32 +01001085 Handle<mirror::Class> h_class = hs.NewHandle(GetClassRoot<mirror::Class>());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001086 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1087 }
1088
1089 // A selection of classes from different core classpath components.
1090 constexpr const char* kTestCases[] = {
1091 "java.net.CookieManager", // From libcore.
1092 "dalvik.system.ClassExt", // From libart.
1093 };
1094
1095 if (in_transaction) {
1096 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1097 // classes isn't transactional. Load them ahead of time.
1098 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1099 for (const char* name : kTestCases) {
1100 class_linker->FindClass(self,
1101 DotToDescriptor(name).c_str(),
1102 ScopedNullHandle<mirror::ClassLoader>());
1103 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1104 }
1105 }
1106
1107 if (!should_succeed) {
1108 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1109 // be recreated at runtime).
1110 PrepareForAborts();
1111 }
1112
1113 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001114 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001115
1116 for (const char* name : kTestCases) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001117 ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001118 CHECK(name_string != nullptr);
1119
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001120 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001121 Runtime::Current()->EnterTransactionMode();
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001122 }
1123 CHECK(!self->IsExceptionPending());
1124
Andreas Gampedbf54032018-06-18 14:47:01 -07001125 runner(self, shadow_frame.get(), name_string, &result);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001126
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001127 if (should_succeed) {
1128 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1129 CHECK(result.GetL() != nullptr) << name;
1130 } else {
1131 CHECK(self->IsExceptionPending()) << name;
1132 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001133 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001134 }
1135 self->ClearException();
1136 }
Chang Xing16d1dd82017-07-20 17:56:26 -07001137
1138 if (in_transaction) {
1139 Runtime::Current()->ExitTransactionMode();
1140 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001141 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001142 }
1143
1144 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1145 Thread* self = Thread::Current();
1146 StackHandleScope<2> hs(self);
1147 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1148
1149 {
1150 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1151
1152 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1153 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1154 class_linker->FindClass(self,
1155 "Ljava/lang/BootClassLoader;",
1156 ScopedNullHandle<mirror::ClassLoader>()));
1157 CHECK(boot_cp_class != nullptr);
1158 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1159
1160 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1161 CHECK(boot_cp != nullptr);
1162
Vladimir Markoba118822017-06-12 15:41:56 +01001163 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1164 "()V", class_linker->GetImagePointerSize());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001165 CHECK(boot_cp_init != nullptr);
1166
1167 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001168 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, boot_cp_init, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001169 shadow_frame->SetVRegReference(0, boot_cp.Get());
1170
1171 // create instruction data for invoke-direct {v0} of method with fake index
1172 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001173
1174 interpreter::DoCall<false, false>(boot_cp_init,
1175 self,
1176 *shadow_frame,
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001177 Instruction::At(inst_data),
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001178 inst_data[0],
1179 &result);
1180 CHECK(!self->IsExceptionPending());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001181 }
1182
1183 return boot_cp.Get();
1184 }
1185};
1186
1187TEST_F(UnstartedClassForNameTest, ClassForName) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001188 auto runner = [](Thread* self,
1189 ShadowFrame* shadow_frame,
1190 ObjPtr<mirror::String> name,
1191 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001192 shadow_frame->SetVRegReference(0, name);
1193 UnstartedClassForName(self, shadow_frame, result, 0);
1194 };
1195 RunTest(runner, false, true);
1196}
1197
1198TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001199 auto runner = [](Thread* self,
1200 ShadowFrame* shadow_frame,
1201 ObjPtr<mirror::String> name,
1202 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001203 shadow_frame->SetVRegReference(0, name);
1204 shadow_frame->SetVReg(1, 0);
1205 shadow_frame->SetVRegReference(2, nullptr);
1206 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1207 };
1208 RunTest(runner, false, true);
1209}
1210
1211TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1212 Thread* self = Thread::Current();
1213 ScopedObjectAccess soa(self);
1214
1215 StackHandleScope<1> hs(self);
1216 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1217
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001218 auto runner = [&](Thread* th,
1219 ShadowFrame* shadow_frame,
1220 ObjPtr<mirror::String> name,
1221 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001222 shadow_frame->SetVRegReference(0, name);
1223 shadow_frame->SetVReg(1, 0);
1224 shadow_frame->SetVRegReference(2, boot_cp.Get());
1225 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1226 };
1227 RunTest(runner, false, true);
1228}
1229
1230TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1231 Thread* self = Thread::Current();
1232 ScopedObjectAccess soa(self);
1233
1234 StackHandleScope<1> hs(self);
1235 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1236
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001237 auto runner = [&](Thread* th,
1238 ShadowFrame* shadow_frame,
1239 ObjPtr<mirror::String> name,
1240 JValue* result)
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001241 REQUIRES_SHARED(Locks::mutator_lock_) {
1242 shadow_frame->SetVRegReference(0, name);
1243 shadow_frame->SetVReg(1, 0);
1244 shadow_frame->SetVRegReference(2, boot_cp.Get());
1245 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1246 };
1247 RunTest(runner, true, true);
1248}
1249
1250TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1251 Thread* self = Thread::Current();
1252 ScopedObjectAccess soa(self);
1253
1254 StackHandleScope<2> hs(self);
1255 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1256 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1257 ASSERT_TRUE(path_jobj != nullptr);
1258 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1259 self->DecodeJObject(path_jobj)->AsClassLoader());
1260
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001261 auto runner = [&](Thread* th,
1262 ShadowFrame* shadow_frame,
1263 ObjPtr<mirror::String> name,
1264 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001265 shadow_frame->SetVRegReference(0, name);
1266 shadow_frame->SetVReg(1, 0);
1267 shadow_frame->SetVRegReference(2, path_cp.Get());
1268 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1269 };
1270 RunTest(runner, true, false);
1271}
1272
Andreas Gampe9486a162017-02-16 15:17:47 -08001273TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1274 Thread* self = Thread::Current();
1275 ScopedObjectAccess soa(self);
1276
1277 StackHandleScope<1> hs(self);
1278 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1279 Handle<mirror::Class> list_class = hs.NewHandle(
1280 class_linker->FindClass(self,
1281 "Ljava/util/List;",
1282 ScopedNullHandle<mirror::ClassLoader>()));
1283 ASSERT_TRUE(list_class.Get() != nullptr);
1284 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1285
1286 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001287 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001288
1289 shadow_frame->SetVRegReference(0, list_class.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001290 UnstartedClassGetSignatureAnnotation(self, shadow_frame.get(), &result, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001291 ASSERT_TRUE(result.GetL() != nullptr);
1292 ASSERT_FALSE(self->IsExceptionPending());
1293
Andreas Gampe9486a162017-02-16 15:17:47 -08001294 ASSERT_TRUE(result.GetL()->IsObjectArray());
1295 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1296 result.GetL()->AsObjectArray<mirror::Object>();
1297 std::ostringstream oss;
1298 for (int32_t i = 0; i != array->GetLength(); ++i) {
1299 ObjPtr<mirror::Object> elem = array->Get(i);
1300 ASSERT_TRUE(elem != nullptr);
1301 ASSERT_TRUE(elem->IsString());
1302 oss << elem->AsString()->ToModifiedUtf8();
1303 }
1304 std::string output_string = oss.str();
1305 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1306}
1307
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001308TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1309 Thread* self = Thread::Current();
1310 ScopedObjectAccess soa(self);
1311
1312 StackHandleScope<4> hs(self);
1313 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1314
1315 // Get Throwable.
Vladimir Markoadbceb72018-05-29 14:34:14 +01001316 Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001317 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1318
1319 // Get an input object.
1320 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1321
1322 // Find the constructor.
Vladimir Markoba118822017-06-12 15:41:56 +01001323 ArtMethod* throw_cons = throw_class->FindConstructor(
1324 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001325 ASSERT_TRUE(throw_cons != nullptr);
Chang Xingfef27c22017-07-11 09:57:44 -07001326 Handle<mirror::Constructor> cons;
1327 if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1328 cons = hs.NewHandle(
1329 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1330 ASSERT_TRUE(cons != nullptr);
1331 } else {
1332 cons = hs.NewHandle(
1333 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1334 ASSERT_TRUE(cons != nullptr);
1335 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001336
1337 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
Andreas Gampec6ea7d02017-02-01 16:46:28 -08001338 mirror::ObjectArray<mirror::Object>::Alloc(
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001339 self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001340 ASSERT_TRUE(args != nullptr);
1341 args->Set(0, input.Get());
1342
1343 // OK, we're ready now.
1344 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001345 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001346 shadow_frame->SetVRegReference(0, cons.Get());
1347 shadow_frame->SetVRegReference(1, args.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001348 UnstartedConstructorNewInstance0(self, shadow_frame.get(), &result, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001349
1350 ASSERT_TRUE(result.GetL() != nullptr);
1351 ASSERT_FALSE(self->IsExceptionPending());
1352
1353 // Should be a new object.
1354 ASSERT_NE(result.GetL(), input.Get());
Vladimir Markoadbceb72018-05-29 14:34:14 +01001355 // Should be of type Throwable.
1356 ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001357 // Should have the right string.
1358 ObjPtr<mirror::String> result_msg =
1359 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001360 EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001361}
1362
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001363TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1364 Thread* self = Thread::Current();
1365 ScopedObjectAccess soa(self);
Andreas Gampedbf54032018-06-18 14:47:01 -07001366 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001367
1368 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001369 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001370
1371 EXPECT_EQ(0, result.GetI());
1372 ASSERT_FALSE(self->IsExceptionPending());
1373
1374 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001375 tmp->SetVRegReference(0, str);
Andreas Gampedbf54032018-06-18 14:47:01 -07001376 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001377 EXPECT_NE(0, result.GetI());
1378 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1379 ASSERT_FALSE(self->IsExceptionPending());
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001380}
1381
Andreas Gampe799681b2015-05-15 19:24:12 -07001382} // namespace interpreter
1383} // namespace art