blob: 4429f6371dbbb1c3ace750d8a57951005d38bf48 [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 Gampe70f5fd02018-10-24 19:58:37 -070034#include "mirror/class-alloc-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070035#include "mirror/class_loader.h"
Andreas Gampe9486a162017-02-16 15:17:47 -080036#include "mirror/object-inl.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -070037#include "mirror/object_array-alloc-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070038#include "mirror/object_array-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070039#include "mirror/string-inl.h"
40#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070041#include "scoped_thread_state_change-inl.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010042#include "shadow_frame-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070043#include "thread.h"
Andreas Gampe8ce9c302016-04-15 21:24:28 -070044#include "transaction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070045
46namespace art {
47namespace interpreter {
48
Andreas Gampedbf54032018-06-18 14:47:01 -070049// Deleter to be used with ShadowFrame::CreateDeoptimizedFrame objects.
50struct DeoptShadowFrameDelete {
51 // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
52 void operator()(ShadowFrame* ptr) const {
53 if (ptr != nullptr) {
54 ShadowFrame::DeleteDeoptimizedFrame(ptr);
55 }
56 }
57};
58// Alias for std::unique_ptr<> that uses the above deleter.
59using UniqueDeoptShadowFramePtr = std::unique_ptr<ShadowFrame, DeoptShadowFrameDelete>;
60
Andreas Gampe799681b2015-05-15 19:24:12 -070061class UnstartedRuntimeTest : public CommonRuntimeTest {
62 protected:
63 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
64 // test friends.
65
66 // Methods that intercept available libcore implementations.
67#define UNSTARTED_DIRECT(Name, SigIgnored) \
68 static void Unstarted ## Name(Thread* self, \
69 ShadowFrame* shadow_frame, \
70 JValue* result, \
71 size_t arg_offset) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070072 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070073 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
74 }
75#include "unstarted_runtime_list.h"
76 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
77#undef UNSTARTED_RUNTIME_DIRECT_LIST
78#undef UNSTARTED_RUNTIME_JNI_LIST
79#undef UNSTARTED_DIRECT
80
81 // Methods that are native.
Mathieu Chartiere401d142015-04-22 13:56:20 -070082#define UNSTARTED_JNI(Name, SigIgnored) \
Andreas Gampe799681b2015-05-15 19:24:12 -070083 static void UnstartedJNI ## Name(Thread* self, \
Mathieu Chartiere401d142015-04-22 13:56:20 -070084 ArtMethod* method, \
Andreas Gampe799681b2015-05-15 19:24:12 -070085 mirror::Object* receiver, \
86 uint32_t* args, \
87 JValue* result) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070088 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070089 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
90 }
91#include "unstarted_runtime_list.h"
92 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
93#undef UNSTARTED_RUNTIME_DIRECT_LIST
94#undef UNSTARTED_RUNTIME_JNI_LIST
95#undef UNSTARTED_JNI
Andreas Gampe85a098a2016-03-31 13:30:53 -070096
Andreas Gampedbf54032018-06-18 14:47:01 -070097 UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs,
98 ShadowFrame* link,
99 ArtMethod* method,
100 uint32_t dex_pc) {
101 return UniqueDeoptShadowFramePtr(
102 ShadowFrame::CreateDeoptimizedFrame(num_vregs, link, method, dex_pc));
103 }
104
Andreas Gampe85a098a2016-03-31 13:30:53 -0700105 // Helpers for ArrayCopy.
106 //
107 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
108 // of three everywhere. That is enough to test all cases.
109
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100110 static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
Andreas Gampe85a098a2016-03-31 13:30:53 -0700111 Thread* self,
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700112 ObjPtr<mirror::Class> component_type,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700113 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700114 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700115 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700116 ObjPtr<mirror::Class> array_type =
Vladimir Markobcf17522018-06-01 13:14:32 +0100117 runtime->GetClassLinker()->FindArrayClass(self, component_type);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700118 CHECK(array_type != nullptr);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700119 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
Andreas Gampe85a098a2016-03-31 13:30:53 -0700120 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
121 CHECK(result != nullptr);
122 for (size_t i = 0; i < 3; ++i) {
123 result->Set(static_cast<int32_t>(i), data.GetReference(i));
124 CHECK(!self->IsExceptionPending());
125 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100126 return result;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700127 }
128
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100129 static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700130 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700131 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700132 CHECK_EQ(array->GetLength(), 3);
133 CHECK_EQ(data.NumberOfReferences(), 3U);
134 for (size_t i = 0; i < 3; ++i) {
Vladimir Marko423bebb2019-03-26 15:17:21 +0000135 EXPECT_OBJ_PTR_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700136 }
137 }
138
139 void RunArrayCopy(Thread* self,
140 ShadowFrame* tmp,
141 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100142 ObjPtr<mirror::ObjectArray<mirror::Object>> src,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700143 int32_t src_pos,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100144 ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700145 int32_t dst_pos,
146 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700147 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700148 JValue result;
149 tmp->SetVRegReference(0, src);
150 tmp->SetVReg(1, src_pos);
151 tmp->SetVRegReference(2, dst);
152 tmp->SetVReg(3, dst_pos);
153 tmp->SetVReg(4, length);
154 UnstartedSystemArraycopy(self, tmp, &result, 0);
155 bool exception_pending = self->IsExceptionPending();
156 EXPECT_EQ(exception_pending, expect_exception);
157 if (exception_pending) {
158 self->ClearException();
159 }
160 }
161
162 void RunArrayCopy(Thread* self,
163 ShadowFrame* tmp,
164 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100165 ObjPtr<mirror::Class> src_component_class,
166 ObjPtr<mirror::Class> dst_component_class,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700167 const StackHandleScope<3>& src_data,
168 int32_t src_pos,
169 const StackHandleScope<3>& dst_data,
170 int32_t dst_pos,
171 int32_t length,
172 const StackHandleScope<3>& expected_result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700173 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700174 StackHandleScope<3> hs_misc(self);
175 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
176
177 Handle<mirror::ObjectArray<mirror::Object>> src_handle(
178 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
179
180 Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
181 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
182
183 RunArrayCopy(self,
184 tmp,
185 expect_exception,
186 src_handle.Get(),
187 src_pos,
188 dst_handle.Get(),
189 dst_pos,
190 length);
191 CheckObjectArray(dst_handle.Get(), expected_result);
192 }
Andreas Gampe89e3b482016-04-12 18:07:36 -0700193
194 void TestCeilFloor(bool ceil,
195 Thread* self,
196 ShadowFrame* tmp,
197 double const test_pairs[][2],
198 size_t num_pairs)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700199 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700200 for (size_t i = 0; i < num_pairs; ++i) {
201 tmp->SetVRegDouble(0, test_pairs[i][0]);
202
203 JValue result;
204 if (ceil) {
205 UnstartedMathCeil(self, tmp, &result, 0);
206 } else {
207 UnstartedMathFloor(self, tmp, &result, 0);
208 }
209
210 ASSERT_FALSE(self->IsExceptionPending());
211
212 // We want precise results.
213 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
214 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
215 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
216 }
217 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700218
219 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
220 // loading code doesn't work under transactions.
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700221 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100222 ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700223 Thread::Current(),
224 Transaction::kAbortExceptionSignature,
225 ScopedNullHandle<mirror::ClassLoader>());
226 CHECK(result != nullptr);
227 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700228};
229
230TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
231 Thread* self = Thread::Current();
232
233 ScopedObjectAccess soa(self);
234 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
235 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
236 const uint8_t* base_ptr = base_array;
237
238 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700239 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700240
241 for (int32_t i = 0; i < kBaseLen; ++i) {
242 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
243
Andreas Gampedbf54032018-06-18 14:47:01 -0700244 UnstartedMemoryPeekByte(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700245
246 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
247 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700248}
249
250TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
251 Thread* self = Thread::Current();
252
253 ScopedObjectAccess soa(self);
254 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
255 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
256 const uint8_t* base_ptr = base_array;
257
258 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700259 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700260
261 int32_t adjusted_length = kBaseLen - sizeof(int16_t);
262 for (int32_t i = 0; i < adjusted_length; ++i) {
263 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
264
Andreas Gampedbf54032018-06-18 14:47:01 -0700265 UnstartedMemoryPeekShort(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700266
Andreas Gampec55bb392018-09-21 00:02:02 +0000267 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700268 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
269 EXPECT_EQ(result.GetS(), *short_ptr);
270 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700271}
272
273TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
274 Thread* self = Thread::Current();
275
276 ScopedObjectAccess soa(self);
277 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
278 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
279 const uint8_t* base_ptr = base_array;
280
281 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700282 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700283
284 int32_t adjusted_length = kBaseLen - sizeof(int32_t);
285 for (int32_t i = 0; i < adjusted_length; ++i) {
286 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
287
Andreas Gampedbf54032018-06-18 14:47:01 -0700288 UnstartedMemoryPeekInt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700289
Andreas Gampec55bb392018-09-21 00:02:02 +0000290 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700291 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
292 EXPECT_EQ(result.GetI(), *int_ptr);
293 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700294}
295
296TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
297 Thread* self = Thread::Current();
298
299 ScopedObjectAccess soa(self);
300 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
301 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
302 const uint8_t* base_ptr = base_array;
303
304 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700305 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700306
307 int32_t adjusted_length = kBaseLen - sizeof(int64_t);
308 for (int32_t i = 0; i < adjusted_length; ++i) {
309 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
310
Andreas Gampedbf54032018-06-18 14:47:01 -0700311 UnstartedMemoryPeekLong(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700312
Andreas Gampec55bb392018-09-21 00:02:02 +0000313 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700314 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
315 EXPECT_EQ(result.GetJ(), *long_ptr);
316 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700317}
318
319TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
320 Thread* self = Thread::Current();
321
322 ScopedObjectAccess soa(self);
323 StackHandleScope<2> hs(self);
324 // TODO: Actual UTF.
325 constexpr const char base_string[] = "abcdefghijklmnop";
326 Handle<mirror::String> h_test_string(hs.NewHandle(
327 mirror::String::AllocFromModifiedUtf8(self, base_string)));
328 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
329 Handle<mirror::CharArray> h_char_array(hs.NewHandle(
330 mirror::CharArray::Alloc(self, kBaseLen)));
331 // A buffer so we can make sure we only modify the elements targetted.
332 uint16_t buf[kBaseLen];
333
334 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700335 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700336
337 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
338 for (int32_t count = 0; count <= kBaseLen; ++count) {
339 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
340 // Only do it when in bounds.
341 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
342 tmp->SetVRegReference(0, h_test_string.Get());
343 tmp->SetVReg(1, start_index);
344 tmp->SetVReg(2, count);
345 tmp->SetVRegReference(3, h_char_array.Get());
346 tmp->SetVReg(3, trg_offset);
347
348 // Copy the char_array into buf.
349 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
350
Andreas Gampedbf54032018-06-18 14:47:01 -0700351 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700352
353 uint16_t* data = h_char_array->GetData();
354
355 bool success = true;
356
357 // First segment should be unchanged.
358 for (int32_t i = 0; i < trg_offset; ++i) {
359 success = success && (data[i] == buf[i]);
360 }
361 // Second segment should be a copy.
362 for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
363 success = success && (data[i] == buf[i - trg_offset + start_index]);
364 }
365 // Third segment should be unchanged.
366 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
367 success = success && (data[i] == buf[i]);
368 }
369
370 EXPECT_TRUE(success);
371 }
372 }
373 }
374 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700375}
376
377TEST_F(UnstartedRuntimeTest, StringCharAt) {
378 Thread* self = Thread::Current();
379
380 ScopedObjectAccess soa(self);
381 // TODO: Actual UTF.
382 constexpr const char* base_string = "abcdefghijklmnop";
383 int32_t base_len = static_cast<int32_t>(strlen(base_string));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100384 ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
Andreas Gampe799681b2015-05-15 19:24:12 -0700385
386 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700387 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700388
389 for (int32_t i = 0; i < base_len; ++i) {
390 tmp->SetVRegReference(0, test_string);
391 tmp->SetVReg(1, i);
392
Andreas Gampedbf54032018-06-18 14:47:01 -0700393 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700394
395 EXPECT_EQ(result.GetI(), base_string[i]);
396 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700397}
398
Jeff Hao400ce002015-05-29 10:53:17 -0700399TEST_F(UnstartedRuntimeTest, StringInit) {
400 Thread* self = Thread::Current();
401 ScopedObjectAccess soa(self);
Vladimir Markoacb906d2018-05-30 10:23:49 +0100402 ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
Chang Xingfef27c22017-07-11 09:57:44 -0700403 ArtMethod* method =
Vladimir Markoba118822017-06-12 15:41:56 +0100404 klass->FindConstructor("(Ljava/lang/String;)V",
405 Runtime::Current()->GetClassLinker()->GetImagePointerSize());
406 ASSERT_TRUE(method != nullptr);
Jeff Hao400ce002015-05-29 10:53:17 -0700407
408 // create instruction data for invoke-direct {v0, v1} of method with fake index
409 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Jeff Hao400ce002015-05-29 10:53:17 -0700410
411 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700412 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
Jeff Hao400ce002015-05-29 10:53:17 -0700413 const char* base_string = "hello_world";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100414 StackHandleScope<2> hs(self);
415 Handle<mirror::String> string_arg =
416 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
417 Handle<mirror::String> reference_empty_string =
418 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
419 shadow_frame->SetVRegReference(0, reference_empty_string.Get());
420 shadow_frame->SetVRegReference(1, string_arg.Get());
Jeff Hao400ce002015-05-29 10:53:17 -0700421
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700422 interpreter::DoCall<false, false>(method,
423 self,
424 *shadow_frame,
425 Instruction::At(inst_data),
426 inst_data[0],
427 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100428 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Jeff Hao400ce002015-05-29 10:53:17 -0700429 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700430
431 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
432 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
433 string_arg->GetLength() * sizeof(uint8_t)), 0);
434 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
435 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
436 string_arg->GetLength() * sizeof(uint16_t)), 0);
437 } else {
438 bool equal = true;
439 for (int i = 0; i < string_arg->GetLength(); ++i) {
440 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
441 equal = false;
442 break;
443 }
444 }
445 EXPECT_EQ(equal, true);
446 }
Jeff Hao400ce002015-05-29 10:53:17 -0700447}
448
Andreas Gampe85a098a2016-03-31 13:30:53 -0700449// Tests the exceptions that should be checked before modifying the destination.
450// (Doesn't check the object vs primitive case ATM.)
451TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
452 Thread* self = Thread::Current();
453 ScopedObjectAccess soa(self);
454 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700455 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700456
457 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
458 // allocate.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100459 StackHandleScope<3> hs_misc(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100460 Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700461
462 StackHandleScope<3> hs_data(self);
463 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
464 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
465 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
466
467 Handle<mirror::ObjectArray<mirror::Object>> array(
468 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
469
Andreas Gampedbf54032018-06-18 14:47:01 -0700470 RunArrayCopy(self, tmp.get(), true, array.Get(), -1, array.Get(), 0, 0);
471 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), -1, 0);
472 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, -1);
473 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, 4);
474 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 1, 3);
475 RunArrayCopy(self, tmp.get(), true, array.Get(), 1, array.Get(), 0, 3);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700476
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100477 Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
478 hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
Andreas Gampedbf54032018-06-18 14:47:01 -0700479 RunArrayCopy(self, tmp.get(), true, class_as_array.Get(), 0, array.Get(), 0, 0);
480 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, class_as_array.Get(), 0, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700481}
482
483TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
484 Thread* self = Thread::Current();
485 ScopedObjectAccess soa(self);
486 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700487 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700488
489 StackHandleScope<1> hs_object(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100490 Handle<mirror::Class> object_class(hs_object.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700491
492 // Simple test:
493 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
494 {
495 StackHandleScope<3> hs_src(self);
496 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
497 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
498 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
499
500 StackHandleScope<3> hs_dst(self);
501 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
502 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
503 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
504
505 StackHandleScope<3> hs_expected(self);
506 hs_expected.NewHandle(hs_dst.GetReference(0));
507 hs_expected.NewHandle(hs_dst.GetReference(1));
508 hs_expected.NewHandle(hs_src.GetReference(1));
509
510 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700511 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700512 false,
513 object_class.Get(),
514 object_class.Get(),
515 hs_src,
516 1,
517 hs_dst,
518 2,
519 1,
520 hs_expected);
521 }
522
523 // Simple test:
524 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
525 {
526 StackHandleScope<3> hs_src(self);
527 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
528 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
529 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
530
531 StackHandleScope<3> hs_dst(self);
532 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
533 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
534 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
535
536 StackHandleScope<3> hs_expected(self);
537 hs_expected.NewHandle(hs_dst.GetReference(0));
538 hs_expected.NewHandle(hs_src.GetReference(1));
539 hs_expected.NewHandle(hs_dst.GetReference(2));
540
541 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700542 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700543 false,
544 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100545 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700546 hs_src,
547 1,
548 hs_dst,
549 1,
550 1,
551 hs_expected);
552 }
553
554 // Simple test:
555 // [1,*,3] into [4,5,6] = [1,5,6] + exc
556 {
557 StackHandleScope<3> hs_src(self);
558 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
Vladimir Markoacb906d2018-05-30 10:23:49 +0100559 hs_src.NewHandle(GetClassRoot<mirror::String>());
Andreas Gampe85a098a2016-03-31 13:30:53 -0700560 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
561
562 StackHandleScope<3> hs_dst(self);
563 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
564 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
565 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
566
567 StackHandleScope<3> hs_expected(self);
568 hs_expected.NewHandle(hs_src.GetReference(0));
569 hs_expected.NewHandle(hs_dst.GetReference(1));
570 hs_expected.NewHandle(hs_dst.GetReference(2));
571
572 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700573 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700574 true,
575 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100576 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700577 hs_src,
578 0,
579 hs_dst,
580 0,
581 3,
582 hs_expected);
583 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700584}
585
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700586TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
587 Thread* self = Thread::Current();
588 ScopedObjectAccess soa(self);
589
Andreas Gampedbf54032018-06-18 14:47:01 -0700590 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700591
592 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
593 // suffixes).
594 constexpr const char* test_string = "-2147483646";
595 constexpr int32_t test_values[] = {
596 6,
597 46,
598 646,
599 3646,
600 83646,
601 483646,
602 7483646,
603 47483646,
604 147483646,
605 2147483646,
606 -2147483646
607 };
608
609 static_assert(arraysize(test_values) == 11U, "test_values");
610 CHECK_EQ(strlen(test_string), 11U);
611
612 for (size_t i = 0; i <= 10; ++i) {
613 const char* test_value = &test_string[10 - i];
614
615 StackHandleScope<1> hs_str(self);
616 Handle<mirror::String> h_str(
617 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
618 ASSERT_NE(h_str.Get(), nullptr);
619 ASSERT_FALSE(self->IsExceptionPending());
620
621 tmp->SetVRegReference(0, h_str.Get());
622
623 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700624 UnstartedIntegerParseInt(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700625
626 ASSERT_FALSE(self->IsExceptionPending());
627 EXPECT_EQ(result.GetI(), test_values[i]);
628 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700629}
630
631// Right now the same as Integer.Parse
632TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
633 Thread* self = Thread::Current();
634 ScopedObjectAccess soa(self);
635
Andreas Gampedbf54032018-06-18 14:47:01 -0700636 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700637
638 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
639 // suffixes).
640 constexpr const char* test_string = "-2147483646";
641 constexpr int64_t test_values[] = {
642 6,
643 46,
644 646,
645 3646,
646 83646,
647 483646,
648 7483646,
649 47483646,
650 147483646,
651 2147483646,
652 -2147483646
653 };
654
655 static_assert(arraysize(test_values) == 11U, "test_values");
656 CHECK_EQ(strlen(test_string), 11U);
657
658 for (size_t i = 0; i <= 10; ++i) {
659 const char* test_value = &test_string[10 - i];
660
661 StackHandleScope<1> hs_str(self);
662 Handle<mirror::String> h_str(
663 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
664 ASSERT_NE(h_str.Get(), nullptr);
665 ASSERT_FALSE(self->IsExceptionPending());
666
667 tmp->SetVRegReference(0, h_str.Get());
668
669 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700670 UnstartedLongParseLong(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700671
672 ASSERT_FALSE(self->IsExceptionPending());
673 EXPECT_EQ(result.GetJ(), test_values[i]);
674 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700675}
676
Andreas Gampe89e3b482016-04-12 18:07:36 -0700677TEST_F(UnstartedRuntimeTest, Ceil) {
678 Thread* self = Thread::Current();
679 ScopedObjectAccess soa(self);
680
Andreas Gampedbf54032018-06-18 14:47:01 -0700681 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700682
683 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
684 constexpr double inf = std::numeric_limits<double>::infinity();
685 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
686 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
687 constexpr double test_pairs[][2] = {
688 { -0.0, -0.0 },
689 { 0.0, 0.0 },
690 { -0.5, -0.0 },
691 { -1.0, -1.0 },
692 { 0.5, 1.0 },
693 { 1.0, 1.0 },
694 { nan, nan },
695 { inf, inf },
696 { -inf, -inf },
697 { ld1, ld1 },
698 { ld2, ld2 }
699 };
700
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700701 TestCeilFloor(/* ceil= */ true, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700702}
703
704TEST_F(UnstartedRuntimeTest, Floor) {
705 Thread* self = Thread::Current();
706 ScopedObjectAccess soa(self);
707
Andreas Gampedbf54032018-06-18 14:47:01 -0700708 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700709
710 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
711 constexpr double inf = std::numeric_limits<double>::infinity();
712 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
713 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
714 constexpr double test_pairs[][2] = {
715 { -0.0, -0.0 },
716 { 0.0, 0.0 },
717 { -0.5, -1.0 },
718 { -1.0, -1.0 },
719 { 0.5, 0.0 },
720 { 1.0, 1.0 },
721 { nan, nan },
722 { inf, inf },
723 { -inf, -inf },
724 { ld1, ld1 },
725 { ld2, ld2 }
726 };
727
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700728 TestCeilFloor(/* ceil= */ false, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700729}
730
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700731TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
732 Thread* self = Thread::Current();
733 ScopedObjectAccess soa(self);
734
Andreas Gampedbf54032018-06-18 14:47:01 -0700735 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700736
737 std::locale c_locale("C");
738
739 // Check ASCII.
740 for (uint32_t i = 0; i < 128; ++i) {
741 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
742 bool c_lower = std::islower(static_cast<char>(i), c_locale);
743 EXPECT_FALSE(c_upper && c_lower) << i;
744
745 // Check toLowerCase.
746 {
747 JValue result;
748 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700749 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700750 ASSERT_FALSE(self->IsExceptionPending());
751 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
752 if (c_lower) {
753 EXPECT_EQ(i, lower_result);
754 } else if (c_upper) {
755 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
756 lower_result);
757 } else {
758 EXPECT_EQ(i, lower_result);
759 }
760 }
761
762 // Check toUpperCase.
763 {
764 JValue result2;
765 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700766 UnstartedCharacterToUpperCase(self, tmp.get(), &result2, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700767 ASSERT_FALSE(self->IsExceptionPending());
768 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
769 if (c_upper) {
770 EXPECT_EQ(i, upper_result);
771 } else if (c_lower) {
772 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
773 upper_result);
774 } else {
775 EXPECT_EQ(i, upper_result);
776 }
777 }
778 }
779
780 // Check abort for other things. Can't test all.
781
782 PrepareForAborts();
783
784 for (uint32_t i = 128; i < 256; ++i) {
785 {
786 JValue result;
787 tmp->SetVReg(0, static_cast<int32_t>(i));
Vladimir Marko672c0802019-07-26 13:03:13 +0100788 EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700789 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Vladimir Marko672c0802019-07-26 13:03:13 +0100790 ASSERT_TRUE(IsTransactionAborted());
791 ExitTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700792 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700793 }
794 {
795 JValue result;
796 tmp->SetVReg(0, static_cast<int32_t>(i));
Vladimir Marko672c0802019-07-26 13:03:13 +0100797 EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700798 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Vladimir Marko672c0802019-07-26 13:03:13 +0100799 ASSERT_TRUE(IsTransactionAborted());
800 ExitTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700801 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700802 }
803 }
804 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
805 {
806 JValue result;
807 tmp->SetVReg(0, static_cast<int32_t>(i));
Vladimir Marko672c0802019-07-26 13:03:13 +0100808 EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700809 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Vladimir Marko672c0802019-07-26 13:03:13 +0100810 ASSERT_TRUE(IsTransactionAborted());
811 ExitTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700812 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700813 }
814 {
815 JValue result;
816 tmp->SetVReg(0, static_cast<int32_t>(i));
Vladimir Marko672c0802019-07-26 13:03:13 +0100817 EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700818 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Vladimir Marko672c0802019-07-26 13:03:13 +0100819 ASSERT_TRUE(IsTransactionAborted());
820 ExitTransactionMode();
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700821 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700822 }
823 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700824}
825
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700826TEST_F(UnstartedRuntimeTest, Sin) {
827 Thread* self = Thread::Current();
828 ScopedObjectAccess soa(self);
829
Andreas Gampedbf54032018-06-18 14:47:01 -0700830 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700831
832 // Test an important value, PI/6. That's the one we see in practice.
833 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
834 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
835
836 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700837 UnstartedMathSin(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700838
839 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
840 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700841}
842
843TEST_F(UnstartedRuntimeTest, Cos) {
844 Thread* self = Thread::Current();
845 ScopedObjectAccess soa(self);
846
Andreas Gampedbf54032018-06-18 14:47:01 -0700847 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700848
849 // Test an important value, PI/6. That's the one we see in practice.
850 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
851 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
852
853 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700854 UnstartedMathCos(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700855
856 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
857 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700858}
859
860TEST_F(UnstartedRuntimeTest, Pow) {
861 Thread* self = Thread::Current();
862 ScopedObjectAccess soa(self);
863
Andreas Gampedbf54032018-06-18 14:47:01 -0700864 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700865
866 // Test an important pair.
867 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
868 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
869
870 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
871 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
872
873 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700874 UnstartedMathPow(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700875
876 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
877 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700878}
879
Andreas Gampeae78c262017-02-01 20:40:44 -0800880TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
881 Thread* self = Thread::Current();
882 ScopedObjectAccess soa(self);
883
884 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700885 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800886
Vladimir Marko317892b2018-05-31 11:11:32 +0100887 ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
Andreas Gampeae78c262017-02-01 20:40:44 -0800888 shadow_frame->SetVRegReference(0, class_klass);
Andreas Gampedbf54032018-06-18 14:47:01 -0700889 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800890 EXPECT_EQ(result.GetZ(), 0);
891
892 jobject class_loader = LoadDex("Nested");
893 StackHandleScope<1> hs(soa.Self());
894 Handle<mirror::ClassLoader> loader(
895 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100896 ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
Andreas Gampeae78c262017-02-01 20:40:44 -0800897 ASSERT_TRUE(c != nullptr);
898 shadow_frame->SetVRegReference(0, c);
Andreas Gampedbf54032018-06-18 14:47:01 -0700899 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800900 EXPECT_EQ(result.GetZ(), 1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800901}
902
903TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
904 Thread* self = Thread::Current();
905 ScopedObjectAccess soa(self);
906
907 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700908 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800909
910 jobject class_loader = LoadDex("Nested");
911 StackHandleScope<4> hs(self);
912 Handle<mirror::ClassLoader> loader(
913 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
914
915 Handle<mirror::Class> nested_klass(hs.NewHandle(
916 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
917 Handle<mirror::Class> inner_klass(hs.NewHandle(
918 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
919 Handle<mirror::Class> anon_klass(hs.NewHandle(
920 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
921
922 shadow_frame->SetVRegReference(0, nested_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700923 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800924 EXPECT_EQ(result.GetL(), nullptr);
925
926 shadow_frame->SetVRegReference(0, inner_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700927 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800928 EXPECT_EQ(result.GetL(), nested_klass.Get());
929
930 shadow_frame->SetVRegReference(0, anon_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700931 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800932 EXPECT_EQ(result.GetL(), nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800933}
934
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800935TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
936 Thread* self = Thread::Current();
937 ScopedObjectAccess soa(self);
938
939 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700940 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800941
942 StackHandleScope<1> hs(self);
943 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
944
945 // Positive test. See that We get something for float conversion.
946 {
947 Handle<mirror::Class> floating_decimal = hs.NewHandle(
948 class_linker->FindClass(self,
949 "Lsun/misc/FloatingDecimal;",
950 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800951 ASSERT_TRUE(floating_decimal != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800952 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
953
Vladimir Markoba118822017-06-12 15:41:56 +0100954 ArtMethod* caller_method = floating_decimal->FindClassMethod(
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800955 "getBinaryToASCIIBuffer",
956 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
957 class_linker->GetImagePointerSize());
958 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
959 ASSERT_TRUE(caller_method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100960 ASSERT_TRUE(caller_method->IsDirect());
961 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700962 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
963 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800964
Andreas Gampedbf54032018-06-18 14:47:01 -0700965 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800966 EXPECT_TRUE(result.GetL() != nullptr);
967 EXPECT_FALSE(self->IsExceptionPending());
968
Andreas Gampedbf54032018-06-18 14:47:01 -0700969 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800970 }
971
972 // Negative test.
973 PrepareForAborts();
974
975 {
976 // Just use a method in Class.
Vladimir Marko317892b2018-05-31 11:11:32 +0100977 ObjPtr<mirror::Class> class_class = GetClassRoot<mirror::Class>();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800978 ArtMethod* caller_method =
979 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
Andreas Gampedbf54032018-06-18 14:47:01 -0700980 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
981 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800982
Vladimir Marko672c0802019-07-26 13:03:13 +0100983 EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700984 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Vladimir Marko672c0802019-07-26 13:03:13 +0100985 ASSERT_TRUE(IsTransactionAborted());
986 ExitTransactionMode();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800987 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800988 self->ClearException();
989
Andreas Gampedbf54032018-06-18 14:47:01 -0700990 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800991 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800992}
993
994TEST_F(UnstartedRuntimeTest, FloatConversion) {
995 Thread* self = Thread::Current();
996 ScopedObjectAccess soa(self);
997
998 StackHandleScope<1> hs(self);
999 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1000 Handle<mirror::Class> double_class = hs.NewHandle(
1001 class_linker->FindClass(self,
1002 "Ljava/lang/Double;",
1003 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001004 ASSERT_TRUE(double_class != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001005 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1006
Vladimir Markoba118822017-06-12 15:41:56 +01001007 ArtMethod* method = double_class->FindClassMethod("toString",
1008 "(D)Ljava/lang/String;",
1009 class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001010 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +01001011 ASSERT_TRUE(method->IsDirect());
1012 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001013
1014 // create instruction data for invoke-direct {v0, v1} of method with fake index
1015 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001016
1017 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001018 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
1019
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001020 shadow_frame->SetVRegDouble(0, 1.23);
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001021 interpreter::DoCall<false, false>(method,
1022 self,
1023 *shadow_frame,
1024 Instruction::At(inst_data),
1025 inst_data[0],
1026 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001027 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001028 ASSERT_TRUE(string_result != nullptr);
1029
1030 std::string mod_utf = string_result->ToModifiedUtf8();
1031 EXPECT_EQ("1.23", mod_utf);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001032}
1033
Andreas Gampebad529d2017-02-13 18:52:10 -08001034TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1035 Thread* self = Thread::Current();
1036 ScopedObjectAccess soa(self);
1037
1038 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001039 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampebad529d2017-02-13 18:52:10 -08001040
1041 StackHandleScope<1> hs(self);
1042 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1043 Handle<mirror::Class> thread_class = hs.NewHandle(
1044 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1045 ASSERT_TRUE(thread_class.Get() != nullptr);
1046 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1047
1048 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1049 // be recreated at runtime).
1050 PrepareForAborts();
1051
1052 {
Vladimir Marko672c0802019-07-26 13:03:13 +01001053 EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -07001054 UnstartedThreadCurrentThread(self, shadow_frame.get(), &result, 0);
Vladimir Marko672c0802019-07-26 13:03:13 +01001055 ASSERT_TRUE(IsTransactionAborted());
1056 ExitTransactionMode();
Andreas Gampebad529d2017-02-13 18:52:10 -08001057 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampebad529d2017-02-13 18:52:10 -08001058 self->ClearException();
1059 }
Andreas Gampebad529d2017-02-13 18:52:10 -08001060}
1061
1062TEST_F(UnstartedRuntimeTest, LogManager) {
1063 Thread* self = Thread::Current();
1064 ScopedObjectAccess soa(self);
1065
1066 StackHandleScope<1> hs(self);
1067 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1068 Handle<mirror::Class> log_manager_class = hs.NewHandle(
Andreas Gampe9486a162017-02-16 15:17:47 -08001069 class_linker->FindClass(self,
1070 "Ljava/util/logging/LogManager;",
1071 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampebad529d2017-02-13 18:52:10 -08001072 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1073 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1074}
1075
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001076class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1077 public:
1078 template <typename T>
1079 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1080 Thread* self = Thread::Current();
1081 ScopedObjectAccess soa(self);
1082
1083 // Ensure that Class is initialized.
1084 {
1085 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1086 StackHandleScope<1> hs(self);
Vladimir Marko317892b2018-05-31 11:11:32 +01001087 Handle<mirror::Class> h_class = hs.NewHandle(GetClassRoot<mirror::Class>());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001088 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1089 }
1090
1091 // A selection of classes from different core classpath components.
1092 constexpr const char* kTestCases[] = {
1093 "java.net.CookieManager", // From libcore.
1094 "dalvik.system.ClassExt", // From libart.
1095 };
1096
1097 if (in_transaction) {
1098 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1099 // classes isn't transactional. Load them ahead of time.
1100 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1101 for (const char* name : kTestCases) {
1102 class_linker->FindClass(self,
1103 DotToDescriptor(name).c_str(),
1104 ScopedNullHandle<mirror::ClassLoader>());
1105 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1106 }
1107 }
1108
1109 if (!should_succeed) {
1110 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1111 // be recreated at runtime).
1112 PrepareForAborts();
1113 }
1114
1115 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001116 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001117
1118 for (const char* name : kTestCases) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001119 ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001120 CHECK(name_string != nullptr);
1121
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001122 if (in_transaction) {
Vladimir Marko672c0802019-07-26 13:03:13 +01001123 EnterTransactionMode();
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001124 }
1125 CHECK(!self->IsExceptionPending());
1126
Andreas Gampedbf54032018-06-18 14:47:01 -07001127 runner(self, shadow_frame.get(), name_string, &result);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001128
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001129 if (should_succeed) {
1130 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1131 CHECK(result.GetL() != nullptr) << name;
1132 } else {
1133 CHECK(self->IsExceptionPending()) << name;
1134 if (in_transaction) {
Vladimir Marko672c0802019-07-26 13:03:13 +01001135 ASSERT_TRUE(IsTransactionAborted());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001136 }
1137 self->ClearException();
1138 }
Chang Xing16d1dd82017-07-20 17:56:26 -07001139
1140 if (in_transaction) {
Vladimir Marko672c0802019-07-26 13:03:13 +01001141 ExitTransactionMode();
Chang Xing16d1dd82017-07-20 17:56:26 -07001142 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001143 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001144 }
1145
1146 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1147 Thread* self = Thread::Current();
1148 StackHandleScope<2> hs(self);
1149 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1150
1151 {
1152 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1153
1154 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1155 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1156 class_linker->FindClass(self,
1157 "Ljava/lang/BootClassLoader;",
1158 ScopedNullHandle<mirror::ClassLoader>()));
1159 CHECK(boot_cp_class != nullptr);
1160 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1161
1162 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1163 CHECK(boot_cp != nullptr);
1164
Vladimir Markoba118822017-06-12 15:41:56 +01001165 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1166 "()V", class_linker->GetImagePointerSize());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001167 CHECK(boot_cp_init != nullptr);
1168
1169 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001170 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, boot_cp_init, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001171 shadow_frame->SetVRegReference(0, boot_cp.Get());
1172
1173 // create instruction data for invoke-direct {v0} of method with fake index
1174 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001175
1176 interpreter::DoCall<false, false>(boot_cp_init,
1177 self,
1178 *shadow_frame,
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001179 Instruction::At(inst_data),
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001180 inst_data[0],
1181 &result);
1182 CHECK(!self->IsExceptionPending());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001183 }
1184
1185 return boot_cp.Get();
1186 }
1187};
1188
1189TEST_F(UnstartedClassForNameTest, ClassForName) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001190 auto runner = [](Thread* self,
1191 ShadowFrame* shadow_frame,
1192 ObjPtr<mirror::String> name,
1193 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001194 shadow_frame->SetVRegReference(0, name);
1195 UnstartedClassForName(self, shadow_frame, result, 0);
1196 };
1197 RunTest(runner, false, true);
1198}
1199
1200TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001201 auto runner = [](Thread* self,
1202 ShadowFrame* shadow_frame,
1203 ObjPtr<mirror::String> name,
1204 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001205 shadow_frame->SetVRegReference(0, name);
1206 shadow_frame->SetVReg(1, 0);
1207 shadow_frame->SetVRegReference(2, nullptr);
1208 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1209 };
1210 RunTest(runner, false, true);
1211}
1212
1213TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1214 Thread* self = Thread::Current();
1215 ScopedObjectAccess soa(self);
1216
1217 StackHandleScope<1> hs(self);
1218 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1219
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001220 auto runner = [&](Thread* th,
1221 ShadowFrame* shadow_frame,
1222 ObjPtr<mirror::String> name,
1223 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001224 shadow_frame->SetVRegReference(0, name);
1225 shadow_frame->SetVReg(1, 0);
1226 shadow_frame->SetVRegReference(2, boot_cp.Get());
1227 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1228 };
1229 RunTest(runner, false, true);
1230}
1231
1232TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1233 Thread* self = Thread::Current();
1234 ScopedObjectAccess soa(self);
1235
1236 StackHandleScope<1> hs(self);
1237 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1238
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001239 auto runner = [&](Thread* th,
1240 ShadowFrame* shadow_frame,
1241 ObjPtr<mirror::String> name,
1242 JValue* result)
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001243 REQUIRES_SHARED(Locks::mutator_lock_) {
1244 shadow_frame->SetVRegReference(0, name);
1245 shadow_frame->SetVReg(1, 0);
1246 shadow_frame->SetVRegReference(2, boot_cp.Get());
1247 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1248 };
1249 RunTest(runner, true, true);
1250}
1251
1252TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1253 Thread* self = Thread::Current();
1254 ScopedObjectAccess soa(self);
1255
1256 StackHandleScope<2> hs(self);
1257 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1258 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1259 ASSERT_TRUE(path_jobj != nullptr);
1260 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1261 self->DecodeJObject(path_jobj)->AsClassLoader());
1262
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001263 auto runner = [&](Thread* th,
1264 ShadowFrame* shadow_frame,
1265 ObjPtr<mirror::String> name,
1266 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001267 shadow_frame->SetVRegReference(0, name);
1268 shadow_frame->SetVReg(1, 0);
1269 shadow_frame->SetVRegReference(2, path_cp.Get());
1270 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1271 };
1272 RunTest(runner, true, false);
1273}
1274
Andreas Gampe9486a162017-02-16 15:17:47 -08001275TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1276 Thread* self = Thread::Current();
1277 ScopedObjectAccess soa(self);
1278
1279 StackHandleScope<1> hs(self);
1280 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1281 Handle<mirror::Class> list_class = hs.NewHandle(
1282 class_linker->FindClass(self,
1283 "Ljava/util/List;",
1284 ScopedNullHandle<mirror::ClassLoader>()));
1285 ASSERT_TRUE(list_class.Get() != nullptr);
1286 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1287
1288 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001289 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001290
1291 shadow_frame->SetVRegReference(0, list_class.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001292 UnstartedClassGetSignatureAnnotation(self, shadow_frame.get(), &result, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001293 ASSERT_TRUE(result.GetL() != nullptr);
1294 ASSERT_FALSE(self->IsExceptionPending());
1295
Andreas Gampe9486a162017-02-16 15:17:47 -08001296 ASSERT_TRUE(result.GetL()->IsObjectArray());
1297 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1298 result.GetL()->AsObjectArray<mirror::Object>();
1299 std::ostringstream oss;
1300 for (int32_t i = 0; i != array->GetLength(); ++i) {
1301 ObjPtr<mirror::Object> elem = array->Get(i);
1302 ASSERT_TRUE(elem != nullptr);
1303 ASSERT_TRUE(elem->IsString());
1304 oss << elem->AsString()->ToModifiedUtf8();
1305 }
1306 std::string output_string = oss.str();
1307 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1308}
1309
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001310TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1311 Thread* self = Thread::Current();
1312 ScopedObjectAccess soa(self);
1313
1314 StackHandleScope<4> hs(self);
1315 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1316
1317 // Get Throwable.
Vladimir Markoadbceb72018-05-29 14:34:14 +01001318 Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001319 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1320
1321 // Get an input object.
1322 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1323
1324 // Find the constructor.
Vladimir Markoba118822017-06-12 15:41:56 +01001325 ArtMethod* throw_cons = throw_class->FindConstructor(
1326 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001327 ASSERT_TRUE(throw_cons != nullptr);
Chang Xingfef27c22017-07-11 09:57:44 -07001328 Handle<mirror::Constructor> cons;
1329 if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1330 cons = hs.NewHandle(
1331 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1332 ASSERT_TRUE(cons != nullptr);
1333 } else {
1334 cons = hs.NewHandle(
1335 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1336 ASSERT_TRUE(cons != nullptr);
1337 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001338
1339 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
Andreas Gampec6ea7d02017-02-01 16:46:28 -08001340 mirror::ObjectArray<mirror::Object>::Alloc(
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001341 self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001342 ASSERT_TRUE(args != nullptr);
1343 args->Set(0, input.Get());
1344
1345 // OK, we're ready now.
1346 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001347 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001348 shadow_frame->SetVRegReference(0, cons.Get());
1349 shadow_frame->SetVRegReference(1, args.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001350 UnstartedConstructorNewInstance0(self, shadow_frame.get(), &result, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001351
1352 ASSERT_TRUE(result.GetL() != nullptr);
1353 ASSERT_FALSE(self->IsExceptionPending());
1354
1355 // Should be a new object.
1356 ASSERT_NE(result.GetL(), input.Get());
Vladimir Markoadbceb72018-05-29 14:34:14 +01001357 // Should be of type Throwable.
1358 ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001359 // Should have the right string.
1360 ObjPtr<mirror::String> result_msg =
1361 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001362 EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001363}
1364
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001365TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1366 Thread* self = Thread::Current();
1367 ScopedObjectAccess soa(self);
Andreas Gampedbf54032018-06-18 14:47:01 -07001368 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001369
1370 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001371 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001372
1373 EXPECT_EQ(0, result.GetI());
1374 ASSERT_FALSE(self->IsExceptionPending());
1375
1376 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001377 tmp->SetVRegReference(0, str);
Andreas Gampedbf54032018-06-18 14:47:01 -07001378 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001379 EXPECT_NE(0, result.GetI());
1380 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1381 ASSERT_FALSE(self->IsExceptionPending());
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001382}
1383
Andreas Gampe799681b2015-05-15 19:24:12 -07001384} // namespace interpreter
1385} // namespace art