blob: 3fafc31e2190ee89cdaea1502e4ac050c40cf837 [file] [log] [blame]
Andreas Gampe799681b2015-05-15 19:24:12 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "unstarted_runtime.h"
18
Andreas Gampe89e3b482016-04-12 18:07:36 -070019#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070020#include <locale>
Andreas Gampe89e3b482016-04-12 18:07:36 -070021
22#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070023#include "base/enums.h"
Andreas Gampeb6795152016-04-21 17:23:31 -070024#include "base/memory_tool.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070025#include "class_linker.h"
Vladimir Markob4eb1b12018-05-24 11:09:38 +010026#include "class_root.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070027#include "common_runtime_test.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080028#include "dex/descriptors_names.h"
David Sehr9e734c72018-01-04 17:56:19 -080029#include "dex/dex_instruction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070030#include "handle.h"
31#include "handle_scope-inl.h"
Jeff Hao400ce002015-05-29 10:53:17 -070032#include "interpreter/interpreter_common.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070033#include "mirror/class_loader.h"
Andreas Gampe9486a162017-02-16 15:17:47 -080034#include "mirror/object-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070035#include "mirror/object_array-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070036#include "mirror/string-inl.h"
37#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070038#include "scoped_thread_state_change-inl.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010039#include "shadow_frame-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070040#include "thread.h"
Andreas Gampe8ce9c302016-04-15 21:24:28 -070041#include "transaction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070042
43namespace art {
44namespace interpreter {
45
Andreas Gampedbf54032018-06-18 14:47:01 -070046// Deleter to be used with ShadowFrame::CreateDeoptimizedFrame objects.
47struct DeoptShadowFrameDelete {
48 // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
49 void operator()(ShadowFrame* ptr) const {
50 if (ptr != nullptr) {
51 ShadowFrame::DeleteDeoptimizedFrame(ptr);
52 }
53 }
54};
55// Alias for std::unique_ptr<> that uses the above deleter.
56using UniqueDeoptShadowFramePtr = std::unique_ptr<ShadowFrame, DeoptShadowFrameDelete>;
57
Andreas Gampe799681b2015-05-15 19:24:12 -070058class UnstartedRuntimeTest : public CommonRuntimeTest {
59 protected:
60 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
61 // test friends.
62
63 // Methods that intercept available libcore implementations.
64#define UNSTARTED_DIRECT(Name, SigIgnored) \
65 static void Unstarted ## Name(Thread* self, \
66 ShadowFrame* shadow_frame, \
67 JValue* result, \
68 size_t arg_offset) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070069 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070070 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
71 }
72#include "unstarted_runtime_list.h"
73 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
74#undef UNSTARTED_RUNTIME_DIRECT_LIST
75#undef UNSTARTED_RUNTIME_JNI_LIST
76#undef UNSTARTED_DIRECT
77
78 // Methods that are native.
Mathieu Chartiere401d142015-04-22 13:56:20 -070079#define UNSTARTED_JNI(Name, SigIgnored) \
Andreas Gampe799681b2015-05-15 19:24:12 -070080 static void UnstartedJNI ## Name(Thread* self, \
Mathieu Chartiere401d142015-04-22 13:56:20 -070081 ArtMethod* method, \
Andreas Gampe799681b2015-05-15 19:24:12 -070082 mirror::Object* receiver, \
83 uint32_t* args, \
84 JValue* result) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070085 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070086 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
87 }
88#include "unstarted_runtime_list.h"
89 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
90#undef UNSTARTED_RUNTIME_DIRECT_LIST
91#undef UNSTARTED_RUNTIME_JNI_LIST
92#undef UNSTARTED_JNI
Andreas Gampe85a098a2016-03-31 13:30:53 -070093
Andreas Gampedbf54032018-06-18 14:47:01 -070094 UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs,
95 ShadowFrame* link,
96 ArtMethod* method,
97 uint32_t dex_pc) {
98 return UniqueDeoptShadowFramePtr(
99 ShadowFrame::CreateDeoptimizedFrame(num_vregs, link, method, dex_pc));
100 }
101
Andreas Gampe85a098a2016-03-31 13:30:53 -0700102 // Helpers for ArrayCopy.
103 //
104 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
105 // of three everywhere. That is enough to test all cases.
106
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100107 static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
Andreas Gampe85a098a2016-03-31 13:30:53 -0700108 Thread* self,
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700109 ObjPtr<mirror::Class> component_type,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700110 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700111 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700112 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700113 ObjPtr<mirror::Class> array_type =
Vladimir Markobcf17522018-06-01 13:14:32 +0100114 runtime->GetClassLinker()->FindArrayClass(self, component_type);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700115 CHECK(array_type != nullptr);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700116 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
Andreas Gampe85a098a2016-03-31 13:30:53 -0700117 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
118 CHECK(result != nullptr);
119 for (size_t i = 0; i < 3; ++i) {
120 result->Set(static_cast<int32_t>(i), data.GetReference(i));
121 CHECK(!self->IsExceptionPending());
122 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100123 return result;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700124 }
125
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100126 static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700127 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700128 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700129 CHECK_EQ(array->GetLength(), 3);
130 CHECK_EQ(data.NumberOfReferences(), 3U);
131 for (size_t i = 0; i < 3; ++i) {
132 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
133 }
134 }
135
136 void RunArrayCopy(Thread* self,
137 ShadowFrame* tmp,
138 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100139 ObjPtr<mirror::ObjectArray<mirror::Object>> src,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700140 int32_t src_pos,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100141 ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700142 int32_t dst_pos,
143 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700144 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700145 JValue result;
146 tmp->SetVRegReference(0, src);
147 tmp->SetVReg(1, src_pos);
148 tmp->SetVRegReference(2, dst);
149 tmp->SetVReg(3, dst_pos);
150 tmp->SetVReg(4, length);
151 UnstartedSystemArraycopy(self, tmp, &result, 0);
152 bool exception_pending = self->IsExceptionPending();
153 EXPECT_EQ(exception_pending, expect_exception);
154 if (exception_pending) {
155 self->ClearException();
156 }
157 }
158
159 void RunArrayCopy(Thread* self,
160 ShadowFrame* tmp,
161 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100162 ObjPtr<mirror::Class> src_component_class,
163 ObjPtr<mirror::Class> dst_component_class,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700164 const StackHandleScope<3>& src_data,
165 int32_t src_pos,
166 const StackHandleScope<3>& dst_data,
167 int32_t dst_pos,
168 int32_t length,
169 const StackHandleScope<3>& expected_result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700170 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700171 StackHandleScope<3> hs_misc(self);
172 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
173
174 Handle<mirror::ObjectArray<mirror::Object>> src_handle(
175 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
176
177 Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
178 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
179
180 RunArrayCopy(self,
181 tmp,
182 expect_exception,
183 src_handle.Get(),
184 src_pos,
185 dst_handle.Get(),
186 dst_pos,
187 length);
188 CheckObjectArray(dst_handle.Get(), expected_result);
189 }
Andreas Gampe89e3b482016-04-12 18:07:36 -0700190
191 void TestCeilFloor(bool ceil,
192 Thread* self,
193 ShadowFrame* tmp,
194 double const test_pairs[][2],
195 size_t num_pairs)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700196 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700197 for (size_t i = 0; i < num_pairs; ++i) {
198 tmp->SetVRegDouble(0, test_pairs[i][0]);
199
200 JValue result;
201 if (ceil) {
202 UnstartedMathCeil(self, tmp, &result, 0);
203 } else {
204 UnstartedMathFloor(self, tmp, &result, 0);
205 }
206
207 ASSERT_FALSE(self->IsExceptionPending());
208
209 // We want precise results.
210 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
211 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
212 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
213 }
214 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700215
216 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
217 // loading code doesn't work under transactions.
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700218 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100219 ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700220 Thread::Current(),
221 Transaction::kAbortExceptionSignature,
222 ScopedNullHandle<mirror::ClassLoader>());
223 CHECK(result != nullptr);
224 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700225};
226
227TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
228 Thread* self = Thread::Current();
229
230 ScopedObjectAccess soa(self);
231 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
232 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
233 const uint8_t* base_ptr = base_array;
234
235 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700236 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700237
238 for (int32_t i = 0; i < kBaseLen; ++i) {
239 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
240
Andreas Gampedbf54032018-06-18 14:47:01 -0700241 UnstartedMemoryPeekByte(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700242
243 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
244 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700245}
246
247TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
248 Thread* self = Thread::Current();
249
250 ScopedObjectAccess soa(self);
251 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
252 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
253 const uint8_t* base_ptr = base_array;
254
255 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700256 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700257
258 int32_t adjusted_length = kBaseLen - sizeof(int16_t);
259 for (int32_t i = 0; i < adjusted_length; ++i) {
260 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
261
Andreas Gampedbf54032018-06-18 14:47:01 -0700262 UnstartedMemoryPeekShort(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700263
Andreas Gampec55bb392018-09-21 00:02:02 +0000264 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700265 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
266 EXPECT_EQ(result.GetS(), *short_ptr);
267 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700268}
269
270TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
271 Thread* self = Thread::Current();
272
273 ScopedObjectAccess soa(self);
274 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
275 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
276 const uint8_t* base_ptr = base_array;
277
278 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700279 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700280
281 int32_t adjusted_length = kBaseLen - sizeof(int32_t);
282 for (int32_t i = 0; i < adjusted_length; ++i) {
283 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
284
Andreas Gampedbf54032018-06-18 14:47:01 -0700285 UnstartedMemoryPeekInt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700286
Andreas Gampec55bb392018-09-21 00:02:02 +0000287 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700288 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
289 EXPECT_EQ(result.GetI(), *int_ptr);
290 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700291}
292
293TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
294 Thread* self = Thread::Current();
295
296 ScopedObjectAccess soa(self);
297 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
298 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
299 const uint8_t* base_ptr = base_array;
300
301 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700302 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700303
304 int32_t adjusted_length = kBaseLen - sizeof(int64_t);
305 for (int32_t i = 0; i < adjusted_length; ++i) {
306 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
307
Andreas Gampedbf54032018-06-18 14:47:01 -0700308 UnstartedMemoryPeekLong(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700309
Andreas Gampec55bb392018-09-21 00:02:02 +0000310 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700311 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
312 EXPECT_EQ(result.GetJ(), *long_ptr);
313 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700314}
315
316TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
317 Thread* self = Thread::Current();
318
319 ScopedObjectAccess soa(self);
320 StackHandleScope<2> hs(self);
321 // TODO: Actual UTF.
322 constexpr const char base_string[] = "abcdefghijklmnop";
323 Handle<mirror::String> h_test_string(hs.NewHandle(
324 mirror::String::AllocFromModifiedUtf8(self, base_string)));
325 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
326 Handle<mirror::CharArray> h_char_array(hs.NewHandle(
327 mirror::CharArray::Alloc(self, kBaseLen)));
328 // A buffer so we can make sure we only modify the elements targetted.
329 uint16_t buf[kBaseLen];
330
331 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700332 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700333
334 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
335 for (int32_t count = 0; count <= kBaseLen; ++count) {
336 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
337 // Only do it when in bounds.
338 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
339 tmp->SetVRegReference(0, h_test_string.Get());
340 tmp->SetVReg(1, start_index);
341 tmp->SetVReg(2, count);
342 tmp->SetVRegReference(3, h_char_array.Get());
343 tmp->SetVReg(3, trg_offset);
344
345 // Copy the char_array into buf.
346 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
347
Andreas Gampedbf54032018-06-18 14:47:01 -0700348 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700349
350 uint16_t* data = h_char_array->GetData();
351
352 bool success = true;
353
354 // First segment should be unchanged.
355 for (int32_t i = 0; i < trg_offset; ++i) {
356 success = success && (data[i] == buf[i]);
357 }
358 // Second segment should be a copy.
359 for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
360 success = success && (data[i] == buf[i - trg_offset + start_index]);
361 }
362 // Third segment should be unchanged.
363 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
364 success = success && (data[i] == buf[i]);
365 }
366
367 EXPECT_TRUE(success);
368 }
369 }
370 }
371 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700372}
373
374TEST_F(UnstartedRuntimeTest, StringCharAt) {
375 Thread* self = Thread::Current();
376
377 ScopedObjectAccess soa(self);
378 // TODO: Actual UTF.
379 constexpr const char* base_string = "abcdefghijklmnop";
380 int32_t base_len = static_cast<int32_t>(strlen(base_string));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100381 ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
Andreas Gampe799681b2015-05-15 19:24:12 -0700382
383 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700384 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700385
386 for (int32_t i = 0; i < base_len; ++i) {
387 tmp->SetVRegReference(0, test_string);
388 tmp->SetVReg(1, i);
389
Andreas Gampedbf54032018-06-18 14:47:01 -0700390 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700391
392 EXPECT_EQ(result.GetI(), base_string[i]);
393 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700394}
395
Jeff Hao400ce002015-05-29 10:53:17 -0700396TEST_F(UnstartedRuntimeTest, StringInit) {
397 Thread* self = Thread::Current();
398 ScopedObjectAccess soa(self);
Vladimir Markoacb906d2018-05-30 10:23:49 +0100399 ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
Chang Xingfef27c22017-07-11 09:57:44 -0700400 ArtMethod* method =
Vladimir Markoba118822017-06-12 15:41:56 +0100401 klass->FindConstructor("(Ljava/lang/String;)V",
402 Runtime::Current()->GetClassLinker()->GetImagePointerSize());
403 ASSERT_TRUE(method != nullptr);
Jeff Hao400ce002015-05-29 10:53:17 -0700404
405 // create instruction data for invoke-direct {v0, v1} of method with fake index
406 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Jeff Hao400ce002015-05-29 10:53:17 -0700407
408 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700409 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
Jeff Hao400ce002015-05-29 10:53:17 -0700410 const char* base_string = "hello_world";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100411 StackHandleScope<2> hs(self);
412 Handle<mirror::String> string_arg =
413 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
414 Handle<mirror::String> reference_empty_string =
415 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
416 shadow_frame->SetVRegReference(0, reference_empty_string.Get());
417 shadow_frame->SetVRegReference(1, string_arg.Get());
Jeff Hao400ce002015-05-29 10:53:17 -0700418
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700419 interpreter::DoCall<false, false>(method,
420 self,
421 *shadow_frame,
422 Instruction::At(inst_data),
423 inst_data[0],
424 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100425 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Jeff Hao400ce002015-05-29 10:53:17 -0700426 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700427
428 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
429 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
430 string_arg->GetLength() * sizeof(uint8_t)), 0);
431 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
432 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
433 string_arg->GetLength() * sizeof(uint16_t)), 0);
434 } else {
435 bool equal = true;
436 for (int i = 0; i < string_arg->GetLength(); ++i) {
437 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
438 equal = false;
439 break;
440 }
441 }
442 EXPECT_EQ(equal, true);
443 }
Jeff Hao400ce002015-05-29 10:53:17 -0700444}
445
Andreas Gampe85a098a2016-03-31 13:30:53 -0700446// Tests the exceptions that should be checked before modifying the destination.
447// (Doesn't check the object vs primitive case ATM.)
448TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
449 Thread* self = Thread::Current();
450 ScopedObjectAccess soa(self);
451 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700452 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700453
454 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
455 // allocate.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100456 StackHandleScope<3> hs_misc(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100457 Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700458
459 StackHandleScope<3> hs_data(self);
460 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
461 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
462 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
463
464 Handle<mirror::ObjectArray<mirror::Object>> array(
465 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
466
Andreas Gampedbf54032018-06-18 14:47:01 -0700467 RunArrayCopy(self, tmp.get(), true, array.Get(), -1, array.Get(), 0, 0);
468 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), -1, 0);
469 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, -1);
470 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, 4);
471 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 1, 3);
472 RunArrayCopy(self, tmp.get(), true, array.Get(), 1, array.Get(), 0, 3);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700473
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100474 Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
475 hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
Andreas Gampedbf54032018-06-18 14:47:01 -0700476 RunArrayCopy(self, tmp.get(), true, class_as_array.Get(), 0, array.Get(), 0, 0);
477 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, class_as_array.Get(), 0, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700478}
479
480TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
481 Thread* self = Thread::Current();
482 ScopedObjectAccess soa(self);
483 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700484 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700485
486 StackHandleScope<1> hs_object(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100487 Handle<mirror::Class> object_class(hs_object.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700488
489 // Simple test:
490 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
491 {
492 StackHandleScope<3> hs_src(self);
493 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
494 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
495 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
496
497 StackHandleScope<3> hs_dst(self);
498 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
499 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
500 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
501
502 StackHandleScope<3> hs_expected(self);
503 hs_expected.NewHandle(hs_dst.GetReference(0));
504 hs_expected.NewHandle(hs_dst.GetReference(1));
505 hs_expected.NewHandle(hs_src.GetReference(1));
506
507 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700508 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700509 false,
510 object_class.Get(),
511 object_class.Get(),
512 hs_src,
513 1,
514 hs_dst,
515 2,
516 1,
517 hs_expected);
518 }
519
520 // Simple test:
521 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
522 {
523 StackHandleScope<3> hs_src(self);
524 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
525 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
526 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
527
528 StackHandleScope<3> hs_dst(self);
529 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
530 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
531 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
532
533 StackHandleScope<3> hs_expected(self);
534 hs_expected.NewHandle(hs_dst.GetReference(0));
535 hs_expected.NewHandle(hs_src.GetReference(1));
536 hs_expected.NewHandle(hs_dst.GetReference(2));
537
538 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700539 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700540 false,
541 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100542 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700543 hs_src,
544 1,
545 hs_dst,
546 1,
547 1,
548 hs_expected);
549 }
550
551 // Simple test:
552 // [1,*,3] into [4,5,6] = [1,5,6] + exc
553 {
554 StackHandleScope<3> hs_src(self);
555 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
Vladimir Markoacb906d2018-05-30 10:23:49 +0100556 hs_src.NewHandle(GetClassRoot<mirror::String>());
Andreas Gampe85a098a2016-03-31 13:30:53 -0700557 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
558
559 StackHandleScope<3> hs_dst(self);
560 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
561 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
562 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
563
564 StackHandleScope<3> hs_expected(self);
565 hs_expected.NewHandle(hs_src.GetReference(0));
566 hs_expected.NewHandle(hs_dst.GetReference(1));
567 hs_expected.NewHandle(hs_dst.GetReference(2));
568
569 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700570 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700571 true,
572 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100573 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700574 hs_src,
575 0,
576 hs_dst,
577 0,
578 3,
579 hs_expected);
580 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700581}
582
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700583TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
584 Thread* self = Thread::Current();
585 ScopedObjectAccess soa(self);
586
Andreas Gampedbf54032018-06-18 14:47:01 -0700587 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700588
589 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
590 // suffixes).
591 constexpr const char* test_string = "-2147483646";
592 constexpr int32_t test_values[] = {
593 6,
594 46,
595 646,
596 3646,
597 83646,
598 483646,
599 7483646,
600 47483646,
601 147483646,
602 2147483646,
603 -2147483646
604 };
605
606 static_assert(arraysize(test_values) == 11U, "test_values");
607 CHECK_EQ(strlen(test_string), 11U);
608
609 for (size_t i = 0; i <= 10; ++i) {
610 const char* test_value = &test_string[10 - i];
611
612 StackHandleScope<1> hs_str(self);
613 Handle<mirror::String> h_str(
614 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
615 ASSERT_NE(h_str.Get(), nullptr);
616 ASSERT_FALSE(self->IsExceptionPending());
617
618 tmp->SetVRegReference(0, h_str.Get());
619
620 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700621 UnstartedIntegerParseInt(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700622
623 ASSERT_FALSE(self->IsExceptionPending());
624 EXPECT_EQ(result.GetI(), test_values[i]);
625 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700626}
627
628// Right now the same as Integer.Parse
629TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
630 Thread* self = Thread::Current();
631 ScopedObjectAccess soa(self);
632
Andreas Gampedbf54032018-06-18 14:47:01 -0700633 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700634
635 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
636 // suffixes).
637 constexpr const char* test_string = "-2147483646";
638 constexpr int64_t test_values[] = {
639 6,
640 46,
641 646,
642 3646,
643 83646,
644 483646,
645 7483646,
646 47483646,
647 147483646,
648 2147483646,
649 -2147483646
650 };
651
652 static_assert(arraysize(test_values) == 11U, "test_values");
653 CHECK_EQ(strlen(test_string), 11U);
654
655 for (size_t i = 0; i <= 10; ++i) {
656 const char* test_value = &test_string[10 - i];
657
658 StackHandleScope<1> hs_str(self);
659 Handle<mirror::String> h_str(
660 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
661 ASSERT_NE(h_str.Get(), nullptr);
662 ASSERT_FALSE(self->IsExceptionPending());
663
664 tmp->SetVRegReference(0, h_str.Get());
665
666 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700667 UnstartedLongParseLong(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700668
669 ASSERT_FALSE(self->IsExceptionPending());
670 EXPECT_EQ(result.GetJ(), test_values[i]);
671 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700672}
673
Andreas Gampe89e3b482016-04-12 18:07:36 -0700674TEST_F(UnstartedRuntimeTest, Ceil) {
675 Thread* self = Thread::Current();
676 ScopedObjectAccess soa(self);
677
Andreas Gampedbf54032018-06-18 14:47:01 -0700678 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700679
680 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
681 constexpr double inf = std::numeric_limits<double>::infinity();
682 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
683 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
684 constexpr double test_pairs[][2] = {
685 { -0.0, -0.0 },
686 { 0.0, 0.0 },
687 { -0.5, -0.0 },
688 { -1.0, -1.0 },
689 { 0.5, 1.0 },
690 { 1.0, 1.0 },
691 { nan, nan },
692 { inf, inf },
693 { -inf, -inf },
694 { ld1, ld1 },
695 { ld2, ld2 }
696 };
697
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700698 TestCeilFloor(/* ceil= */ true, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700699}
700
701TEST_F(UnstartedRuntimeTest, Floor) {
702 Thread* self = Thread::Current();
703 ScopedObjectAccess soa(self);
704
Andreas Gampedbf54032018-06-18 14:47:01 -0700705 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700706
707 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
708 constexpr double inf = std::numeric_limits<double>::infinity();
709 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
710 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
711 constexpr double test_pairs[][2] = {
712 { -0.0, -0.0 },
713 { 0.0, 0.0 },
714 { -0.5, -1.0 },
715 { -1.0, -1.0 },
716 { 0.5, 0.0 },
717 { 1.0, 1.0 },
718 { nan, nan },
719 { inf, inf },
720 { -inf, -inf },
721 { ld1, ld1 },
722 { ld2, ld2 }
723 };
724
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700725 TestCeilFloor(/* ceil= */ false, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700726}
727
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700728TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
729 Thread* self = Thread::Current();
730 ScopedObjectAccess soa(self);
731
Andreas Gampedbf54032018-06-18 14:47:01 -0700732 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700733
734 std::locale c_locale("C");
735
736 // Check ASCII.
737 for (uint32_t i = 0; i < 128; ++i) {
738 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
739 bool c_lower = std::islower(static_cast<char>(i), c_locale);
740 EXPECT_FALSE(c_upper && c_lower) << i;
741
742 // Check toLowerCase.
743 {
744 JValue result;
745 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700746 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700747 ASSERT_FALSE(self->IsExceptionPending());
748 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
749 if (c_lower) {
750 EXPECT_EQ(i, lower_result);
751 } else if (c_upper) {
752 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
753 lower_result);
754 } else {
755 EXPECT_EQ(i, lower_result);
756 }
757 }
758
759 // Check toUpperCase.
760 {
761 JValue result2;
762 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700763 UnstartedCharacterToUpperCase(self, tmp.get(), &result2, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700764 ASSERT_FALSE(self->IsExceptionPending());
765 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
766 if (c_upper) {
767 EXPECT_EQ(i, upper_result);
768 } else if (c_lower) {
769 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
770 upper_result);
771 } else {
772 EXPECT_EQ(i, upper_result);
773 }
774 }
775 }
776
777 // Check abort for other things. Can't test all.
778
779 PrepareForAborts();
780
781 for (uint32_t i = 128; i < 256; ++i) {
782 {
783 JValue result;
784 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700785 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700786 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700787 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700788 Runtime::Current()->ExitTransactionMode();
789 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700790 }
791 {
792 JValue result;
793 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700794 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700795 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700796 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700797 Runtime::Current()->ExitTransactionMode();
798 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700799 }
800 }
801 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
802 {
803 JValue result;
804 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700805 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700806 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700807 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700808 Runtime::Current()->ExitTransactionMode();
809 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700810 }
811 {
812 JValue result;
813 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700814 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700815 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700816 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700817 Runtime::Current()->ExitTransactionMode();
818 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700819 }
820 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700821}
822
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700823TEST_F(UnstartedRuntimeTest, Sin) {
824 Thread* self = Thread::Current();
825 ScopedObjectAccess soa(self);
826
Andreas Gampedbf54032018-06-18 14:47:01 -0700827 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700828
829 // Test an important value, PI/6. That's the one we see in practice.
830 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
831 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
832
833 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700834 UnstartedMathSin(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700835
836 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
837 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700838}
839
840TEST_F(UnstartedRuntimeTest, Cos) {
841 Thread* self = Thread::Current();
842 ScopedObjectAccess soa(self);
843
Andreas Gampedbf54032018-06-18 14:47:01 -0700844 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700845
846 // Test an important value, PI/6. That's the one we see in practice.
847 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
848 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
849
850 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700851 UnstartedMathCos(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700852
853 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
854 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700855}
856
857TEST_F(UnstartedRuntimeTest, Pow) {
858 Thread* self = Thread::Current();
859 ScopedObjectAccess soa(self);
860
Andreas Gampedbf54032018-06-18 14:47:01 -0700861 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700862
863 // Test an important pair.
864 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
865 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
866
867 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
868 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
869
870 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700871 UnstartedMathPow(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700872
873 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
874 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700875}
876
Andreas Gampeae78c262017-02-01 20:40:44 -0800877TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
878 Thread* self = Thread::Current();
879 ScopedObjectAccess soa(self);
880
881 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700882 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800883
Vladimir Marko317892b2018-05-31 11:11:32 +0100884 ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
Andreas Gampeae78c262017-02-01 20:40:44 -0800885 shadow_frame->SetVRegReference(0, class_klass);
Andreas Gampedbf54032018-06-18 14:47:01 -0700886 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800887 EXPECT_EQ(result.GetZ(), 0);
888
889 jobject class_loader = LoadDex("Nested");
890 StackHandleScope<1> hs(soa.Self());
891 Handle<mirror::ClassLoader> loader(
892 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100893 ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
Andreas Gampeae78c262017-02-01 20:40:44 -0800894 ASSERT_TRUE(c != nullptr);
895 shadow_frame->SetVRegReference(0, c);
Andreas Gampedbf54032018-06-18 14:47:01 -0700896 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800897 EXPECT_EQ(result.GetZ(), 1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800898}
899
900TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
901 Thread* self = Thread::Current();
902 ScopedObjectAccess soa(self);
903
904 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700905 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800906
907 jobject class_loader = LoadDex("Nested");
908 StackHandleScope<4> hs(self);
909 Handle<mirror::ClassLoader> loader(
910 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
911
912 Handle<mirror::Class> nested_klass(hs.NewHandle(
913 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
914 Handle<mirror::Class> inner_klass(hs.NewHandle(
915 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
916 Handle<mirror::Class> anon_klass(hs.NewHandle(
917 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
918
919 shadow_frame->SetVRegReference(0, nested_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700920 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800921 EXPECT_EQ(result.GetL(), nullptr);
922
923 shadow_frame->SetVRegReference(0, inner_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700924 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800925 EXPECT_EQ(result.GetL(), nested_klass.Get());
926
927 shadow_frame->SetVRegReference(0, anon_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700928 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800929 EXPECT_EQ(result.GetL(), nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800930}
931
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800932TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
933 Thread* self = Thread::Current();
934 ScopedObjectAccess soa(self);
935
936 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700937 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800938
939 StackHandleScope<1> hs(self);
940 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
941
942 // Positive test. See that We get something for float conversion.
943 {
944 Handle<mirror::Class> floating_decimal = hs.NewHandle(
945 class_linker->FindClass(self,
946 "Lsun/misc/FloatingDecimal;",
947 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800948 ASSERT_TRUE(floating_decimal != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800949 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
950
Vladimir Markoba118822017-06-12 15:41:56 +0100951 ArtMethod* caller_method = floating_decimal->FindClassMethod(
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800952 "getBinaryToASCIIBuffer",
953 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
954 class_linker->GetImagePointerSize());
955 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
956 ASSERT_TRUE(caller_method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100957 ASSERT_TRUE(caller_method->IsDirect());
958 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700959 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
960 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800961
Andreas Gampedbf54032018-06-18 14:47:01 -0700962 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800963 EXPECT_TRUE(result.GetL() != nullptr);
964 EXPECT_FALSE(self->IsExceptionPending());
965
Andreas Gampedbf54032018-06-18 14:47:01 -0700966 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800967 }
968
969 // Negative test.
970 PrepareForAborts();
971
972 {
973 // Just use a method in Class.
Vladimir Marko317892b2018-05-31 11:11:32 +0100974 ObjPtr<mirror::Class> class_class = GetClassRoot<mirror::Class>();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800975 ArtMethod* caller_method =
976 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
Andreas Gampedbf54032018-06-18 14:47:01 -0700977 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
978 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800979
Chang Xing16d1dd82017-07-20 17:56:26 -0700980 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700981 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700982 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800983 Runtime::Current()->ExitTransactionMode();
984 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800985 self->ClearException();
986
Andreas Gampedbf54032018-06-18 14:47:01 -0700987 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800988 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800989}
990
991TEST_F(UnstartedRuntimeTest, FloatConversion) {
992 Thread* self = Thread::Current();
993 ScopedObjectAccess soa(self);
994
995 StackHandleScope<1> hs(self);
996 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
997 Handle<mirror::Class> double_class = hs.NewHandle(
998 class_linker->FindClass(self,
999 "Ljava/lang/Double;",
1000 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001001 ASSERT_TRUE(double_class != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001002 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1003
Vladimir Markoba118822017-06-12 15:41:56 +01001004 ArtMethod* method = double_class->FindClassMethod("toString",
1005 "(D)Ljava/lang/String;",
1006 class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001007 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +01001008 ASSERT_TRUE(method->IsDirect());
1009 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001010
1011 // create instruction data for invoke-direct {v0, v1} of method with fake index
1012 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001013
1014 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001015 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
1016
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001017 shadow_frame->SetVRegDouble(0, 1.23);
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001018 interpreter::DoCall<false, false>(method,
1019 self,
1020 *shadow_frame,
1021 Instruction::At(inst_data),
1022 inst_data[0],
1023 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001024 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001025 ASSERT_TRUE(string_result != nullptr);
1026
1027 std::string mod_utf = string_result->ToModifiedUtf8();
1028 EXPECT_EQ("1.23", mod_utf);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001029}
1030
Andreas Gampebad529d2017-02-13 18:52:10 -08001031TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1032 Thread* self = Thread::Current();
1033 ScopedObjectAccess soa(self);
1034
1035 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001036 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampebad529d2017-02-13 18:52:10 -08001037
1038 StackHandleScope<1> hs(self);
1039 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1040 Handle<mirror::Class> thread_class = hs.NewHandle(
1041 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1042 ASSERT_TRUE(thread_class.Get() != nullptr);
1043 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1044
1045 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1046 // be recreated at runtime).
1047 PrepareForAborts();
1048
1049 {
Chang Xing16d1dd82017-07-20 17:56:26 -07001050 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -07001051 UnstartedThreadCurrentThread(self, shadow_frame.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001052 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampebad529d2017-02-13 18:52:10 -08001053 Runtime::Current()->ExitTransactionMode();
1054 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampebad529d2017-02-13 18:52:10 -08001055 self->ClearException();
1056 }
Andreas Gampebad529d2017-02-13 18:52:10 -08001057}
1058
1059TEST_F(UnstartedRuntimeTest, LogManager) {
1060 Thread* self = Thread::Current();
1061 ScopedObjectAccess soa(self);
1062
1063 StackHandleScope<1> hs(self);
1064 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1065 Handle<mirror::Class> log_manager_class = hs.NewHandle(
Andreas Gampe9486a162017-02-16 15:17:47 -08001066 class_linker->FindClass(self,
1067 "Ljava/util/logging/LogManager;",
1068 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampebad529d2017-02-13 18:52:10 -08001069 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1070 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1071}
1072
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001073class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1074 public:
1075 template <typename T>
1076 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1077 Thread* self = Thread::Current();
1078 ScopedObjectAccess soa(self);
1079
1080 // Ensure that Class is initialized.
1081 {
1082 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1083 StackHandleScope<1> hs(self);
Vladimir Marko317892b2018-05-31 11:11:32 +01001084 Handle<mirror::Class> h_class = hs.NewHandle(GetClassRoot<mirror::Class>());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001085 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1086 }
1087
1088 // A selection of classes from different core classpath components.
1089 constexpr const char* kTestCases[] = {
1090 "java.net.CookieManager", // From libcore.
1091 "dalvik.system.ClassExt", // From libart.
1092 };
1093
1094 if (in_transaction) {
1095 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1096 // classes isn't transactional. Load them ahead of time.
1097 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1098 for (const char* name : kTestCases) {
1099 class_linker->FindClass(self,
1100 DotToDescriptor(name).c_str(),
1101 ScopedNullHandle<mirror::ClassLoader>());
1102 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1103 }
1104 }
1105
1106 if (!should_succeed) {
1107 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1108 // be recreated at runtime).
1109 PrepareForAborts();
1110 }
1111
1112 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001113 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001114
1115 for (const char* name : kTestCases) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001116 ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001117 CHECK(name_string != nullptr);
1118
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001119 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001120 Runtime::Current()->EnterTransactionMode();
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001121 }
1122 CHECK(!self->IsExceptionPending());
1123
Andreas Gampedbf54032018-06-18 14:47:01 -07001124 runner(self, shadow_frame.get(), name_string, &result);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001125
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001126 if (should_succeed) {
1127 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1128 CHECK(result.GetL() != nullptr) << name;
1129 } else {
1130 CHECK(self->IsExceptionPending()) << name;
1131 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001132 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001133 }
1134 self->ClearException();
1135 }
Chang Xing16d1dd82017-07-20 17:56:26 -07001136
1137 if (in_transaction) {
1138 Runtime::Current()->ExitTransactionMode();
1139 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001140 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001141 }
1142
1143 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1144 Thread* self = Thread::Current();
1145 StackHandleScope<2> hs(self);
1146 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1147
1148 {
1149 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1150
1151 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1152 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1153 class_linker->FindClass(self,
1154 "Ljava/lang/BootClassLoader;",
1155 ScopedNullHandle<mirror::ClassLoader>()));
1156 CHECK(boot_cp_class != nullptr);
1157 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1158
1159 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1160 CHECK(boot_cp != nullptr);
1161
Vladimir Markoba118822017-06-12 15:41:56 +01001162 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1163 "()V", class_linker->GetImagePointerSize());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001164 CHECK(boot_cp_init != nullptr);
1165
1166 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001167 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, boot_cp_init, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001168 shadow_frame->SetVRegReference(0, boot_cp.Get());
1169
1170 // create instruction data for invoke-direct {v0} of method with fake index
1171 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001172
1173 interpreter::DoCall<false, false>(boot_cp_init,
1174 self,
1175 *shadow_frame,
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001176 Instruction::At(inst_data),
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001177 inst_data[0],
1178 &result);
1179 CHECK(!self->IsExceptionPending());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001180 }
1181
1182 return boot_cp.Get();
1183 }
1184};
1185
1186TEST_F(UnstartedClassForNameTest, ClassForName) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001187 auto runner = [](Thread* self,
1188 ShadowFrame* shadow_frame,
1189 ObjPtr<mirror::String> name,
1190 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001191 shadow_frame->SetVRegReference(0, name);
1192 UnstartedClassForName(self, shadow_frame, result, 0);
1193 };
1194 RunTest(runner, false, true);
1195}
1196
1197TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001198 auto runner = [](Thread* self,
1199 ShadowFrame* shadow_frame,
1200 ObjPtr<mirror::String> name,
1201 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001202 shadow_frame->SetVRegReference(0, name);
1203 shadow_frame->SetVReg(1, 0);
1204 shadow_frame->SetVRegReference(2, nullptr);
1205 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1206 };
1207 RunTest(runner, false, true);
1208}
1209
1210TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1211 Thread* self = Thread::Current();
1212 ScopedObjectAccess soa(self);
1213
1214 StackHandleScope<1> hs(self);
1215 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1216
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001217 auto runner = [&](Thread* th,
1218 ShadowFrame* shadow_frame,
1219 ObjPtr<mirror::String> name,
1220 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001221 shadow_frame->SetVRegReference(0, name);
1222 shadow_frame->SetVReg(1, 0);
1223 shadow_frame->SetVRegReference(2, boot_cp.Get());
1224 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1225 };
1226 RunTest(runner, false, true);
1227}
1228
1229TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1230 Thread* self = Thread::Current();
1231 ScopedObjectAccess soa(self);
1232
1233 StackHandleScope<1> hs(self);
1234 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1235
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001236 auto runner = [&](Thread* th,
1237 ShadowFrame* shadow_frame,
1238 ObjPtr<mirror::String> name,
1239 JValue* result)
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001240 REQUIRES_SHARED(Locks::mutator_lock_) {
1241 shadow_frame->SetVRegReference(0, name);
1242 shadow_frame->SetVReg(1, 0);
1243 shadow_frame->SetVRegReference(2, boot_cp.Get());
1244 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1245 };
1246 RunTest(runner, true, true);
1247}
1248
1249TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1250 Thread* self = Thread::Current();
1251 ScopedObjectAccess soa(self);
1252
1253 StackHandleScope<2> hs(self);
1254 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1255 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1256 ASSERT_TRUE(path_jobj != nullptr);
1257 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1258 self->DecodeJObject(path_jobj)->AsClassLoader());
1259
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001260 auto runner = [&](Thread* th,
1261 ShadowFrame* shadow_frame,
1262 ObjPtr<mirror::String> name,
1263 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001264 shadow_frame->SetVRegReference(0, name);
1265 shadow_frame->SetVReg(1, 0);
1266 shadow_frame->SetVRegReference(2, path_cp.Get());
1267 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1268 };
1269 RunTest(runner, true, false);
1270}
1271
Andreas Gampe9486a162017-02-16 15:17:47 -08001272TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1273 Thread* self = Thread::Current();
1274 ScopedObjectAccess soa(self);
1275
1276 StackHandleScope<1> hs(self);
1277 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1278 Handle<mirror::Class> list_class = hs.NewHandle(
1279 class_linker->FindClass(self,
1280 "Ljava/util/List;",
1281 ScopedNullHandle<mirror::ClassLoader>()));
1282 ASSERT_TRUE(list_class.Get() != nullptr);
1283 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1284
1285 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001286 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001287
1288 shadow_frame->SetVRegReference(0, list_class.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001289 UnstartedClassGetSignatureAnnotation(self, shadow_frame.get(), &result, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001290 ASSERT_TRUE(result.GetL() != nullptr);
1291 ASSERT_FALSE(self->IsExceptionPending());
1292
Andreas Gampe9486a162017-02-16 15:17:47 -08001293 ASSERT_TRUE(result.GetL()->IsObjectArray());
1294 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1295 result.GetL()->AsObjectArray<mirror::Object>();
1296 std::ostringstream oss;
1297 for (int32_t i = 0; i != array->GetLength(); ++i) {
1298 ObjPtr<mirror::Object> elem = array->Get(i);
1299 ASSERT_TRUE(elem != nullptr);
1300 ASSERT_TRUE(elem->IsString());
1301 oss << elem->AsString()->ToModifiedUtf8();
1302 }
1303 std::string output_string = oss.str();
1304 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1305}
1306
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001307TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1308 Thread* self = Thread::Current();
1309 ScopedObjectAccess soa(self);
1310
1311 StackHandleScope<4> hs(self);
1312 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1313
1314 // Get Throwable.
Vladimir Markoadbceb72018-05-29 14:34:14 +01001315 Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001316 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1317
1318 // Get an input object.
1319 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1320
1321 // Find the constructor.
Vladimir Markoba118822017-06-12 15:41:56 +01001322 ArtMethod* throw_cons = throw_class->FindConstructor(
1323 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001324 ASSERT_TRUE(throw_cons != nullptr);
Chang Xingfef27c22017-07-11 09:57:44 -07001325 Handle<mirror::Constructor> cons;
1326 if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1327 cons = hs.NewHandle(
1328 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1329 ASSERT_TRUE(cons != nullptr);
1330 } else {
1331 cons = hs.NewHandle(
1332 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1333 ASSERT_TRUE(cons != nullptr);
1334 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001335
1336 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
Andreas Gampec6ea7d02017-02-01 16:46:28 -08001337 mirror::ObjectArray<mirror::Object>::Alloc(
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001338 self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001339 ASSERT_TRUE(args != nullptr);
1340 args->Set(0, input.Get());
1341
1342 // OK, we're ready now.
1343 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001344 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001345 shadow_frame->SetVRegReference(0, cons.Get());
1346 shadow_frame->SetVRegReference(1, args.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001347 UnstartedConstructorNewInstance0(self, shadow_frame.get(), &result, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001348
1349 ASSERT_TRUE(result.GetL() != nullptr);
1350 ASSERT_FALSE(self->IsExceptionPending());
1351
1352 // Should be a new object.
1353 ASSERT_NE(result.GetL(), input.Get());
Vladimir Markoadbceb72018-05-29 14:34:14 +01001354 // Should be of type Throwable.
1355 ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001356 // Should have the right string.
1357 ObjPtr<mirror::String> result_msg =
1358 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001359 EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001360}
1361
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001362TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1363 Thread* self = Thread::Current();
1364 ScopedObjectAccess soa(self);
Andreas Gampedbf54032018-06-18 14:47:01 -07001365 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001366
1367 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001368 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001369
1370 EXPECT_EQ(0, result.GetI());
1371 ASSERT_FALSE(self->IsExceptionPending());
1372
1373 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001374 tmp->SetVRegReference(0, str);
Andreas Gampedbf54032018-06-18 14:47:01 -07001375 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001376 EXPECT_NE(0, result.GetI());
1377 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1378 ASSERT_FALSE(self->IsExceptionPending());
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001379}
1380
Andreas Gampe799681b2015-05-15 19:24:12 -07001381} // namespace interpreter
1382} // namespace art