blob: daaa05d7dfb290b431922efcb107cd22844ca549 [file] [log] [blame]
Andreas Gampe799681b2015-05-15 19:24:12 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "unstarted_runtime.h"
18
Andreas Gampe89e3b482016-04-12 18:07:36 -070019#include <limits>
Andreas Gampe8ce9c302016-04-15 21:24:28 -070020#include <locale>
Andreas Gampe89e3b482016-04-12 18:07:36 -070021
22#include "base/casts.h"
Andreas Gampe542451c2016-07-26 09:02:02 -070023#include "base/enums.h"
Andreas Gampeb6795152016-04-21 17:23:31 -070024#include "base/memory_tool.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070025#include "class_linker.h"
Vladimir Markob4eb1b12018-05-24 11:09:38 +010026#include "class_root.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070027#include "common_runtime_test.h"
David Sehrb2ec9f52018-02-21 13:20:31 -080028#include "dex/descriptors_names.h"
David Sehr9e734c72018-01-04 17:56:19 -080029#include "dex/dex_instruction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070030#include "handle.h"
31#include "handle_scope-inl.h"
Jeff Hao400ce002015-05-29 10:53:17 -070032#include "interpreter/interpreter_common.h"
Andreas Gampe8e0f0432018-10-24 13:38:03 -070033#include "mirror/array-alloc-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070034#include "mirror/class_loader.h"
Andreas Gampe9486a162017-02-16 15:17:47 -080035#include "mirror/object-inl.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -070036#include "mirror/object_array-alloc-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070037#include "mirror/object_array-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070038#include "mirror/string-inl.h"
39#include "runtime.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070040#include "scoped_thread_state_change-inl.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010041#include "shadow_frame-inl.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070042#include "thread.h"
Andreas Gampe8ce9c302016-04-15 21:24:28 -070043#include "transaction.h"
Andreas Gampe799681b2015-05-15 19:24:12 -070044
45namespace art {
46namespace interpreter {
47
Andreas Gampedbf54032018-06-18 14:47:01 -070048// Deleter to be used with ShadowFrame::CreateDeoptimizedFrame objects.
49struct DeoptShadowFrameDelete {
50 // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
51 void operator()(ShadowFrame* ptr) const {
52 if (ptr != nullptr) {
53 ShadowFrame::DeleteDeoptimizedFrame(ptr);
54 }
55 }
56};
57// Alias for std::unique_ptr<> that uses the above deleter.
58using UniqueDeoptShadowFramePtr = std::unique_ptr<ShadowFrame, DeoptShadowFrameDelete>;
59
Andreas Gampe799681b2015-05-15 19:24:12 -070060class UnstartedRuntimeTest : public CommonRuntimeTest {
61 protected:
62 // Re-expose all UnstartedRuntime implementations so we don't need to declare a million
63 // test friends.
64
65 // Methods that intercept available libcore implementations.
66#define UNSTARTED_DIRECT(Name, SigIgnored) \
67 static void Unstarted ## Name(Thread* self, \
68 ShadowFrame* shadow_frame, \
69 JValue* result, \
70 size_t arg_offset) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070071 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070072 interpreter::UnstartedRuntime::Unstarted ## Name(self, shadow_frame, result, arg_offset); \
73 }
74#include "unstarted_runtime_list.h"
75 UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
76#undef UNSTARTED_RUNTIME_DIRECT_LIST
77#undef UNSTARTED_RUNTIME_JNI_LIST
78#undef UNSTARTED_DIRECT
79
80 // Methods that are native.
Mathieu Chartiere401d142015-04-22 13:56:20 -070081#define UNSTARTED_JNI(Name, SigIgnored) \
Andreas Gampe799681b2015-05-15 19:24:12 -070082 static void UnstartedJNI ## Name(Thread* self, \
Mathieu Chartiere401d142015-04-22 13:56:20 -070083 ArtMethod* method, \
Andreas Gampe799681b2015-05-15 19:24:12 -070084 mirror::Object* receiver, \
85 uint32_t* args, \
86 JValue* result) \
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070087 REQUIRES_SHARED(Locks::mutator_lock_) { \
Andreas Gampe799681b2015-05-15 19:24:12 -070088 interpreter::UnstartedRuntime::UnstartedJNI ## Name(self, method, receiver, args, result); \
89 }
90#include "unstarted_runtime_list.h"
91 UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
92#undef UNSTARTED_RUNTIME_DIRECT_LIST
93#undef UNSTARTED_RUNTIME_JNI_LIST
94#undef UNSTARTED_JNI
Andreas Gampe85a098a2016-03-31 13:30:53 -070095
Andreas Gampedbf54032018-06-18 14:47:01 -070096 UniqueDeoptShadowFramePtr CreateShadowFrame(uint32_t num_vregs,
97 ShadowFrame* link,
98 ArtMethod* method,
99 uint32_t dex_pc) {
100 return UniqueDeoptShadowFramePtr(
101 ShadowFrame::CreateDeoptimizedFrame(num_vregs, link, method, dex_pc));
102 }
103
Andreas Gampe85a098a2016-03-31 13:30:53 -0700104 // Helpers for ArrayCopy.
105 //
106 // Note: as we have to use handles, we use StackHandleScope to transfer data. Hardcode a size
107 // of three everywhere. That is enough to test all cases.
108
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100109 static ObjPtr<mirror::ObjectArray<mirror::Object>> CreateObjectArray(
Andreas Gampe85a098a2016-03-31 13:30:53 -0700110 Thread* self,
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700111 ObjPtr<mirror::Class> component_type,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700112 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700113 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700114 Runtime* runtime = Runtime::Current();
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700115 ObjPtr<mirror::Class> array_type =
Vladimir Markobcf17522018-06-01 13:14:32 +0100116 runtime->GetClassLinker()->FindArrayClass(self, component_type);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700117 CHECK(array_type != nullptr);
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700118 ObjPtr<mirror::ObjectArray<mirror::Object>> result =
Andreas Gampe85a098a2016-03-31 13:30:53 -0700119 mirror::ObjectArray<mirror::Object>::Alloc(self, array_type, 3);
120 CHECK(result != nullptr);
121 for (size_t i = 0; i < 3; ++i) {
122 result->Set(static_cast<int32_t>(i), data.GetReference(i));
123 CHECK(!self->IsExceptionPending());
124 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100125 return result;
Andreas Gampe85a098a2016-03-31 13:30:53 -0700126 }
127
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100128 static void CheckObjectArray(ObjPtr<mirror::ObjectArray<mirror::Object>> array,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700129 const StackHandleScope<3>& data)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700130 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700131 CHECK_EQ(array->GetLength(), 3);
132 CHECK_EQ(data.NumberOfReferences(), 3U);
133 for (size_t i = 0; i < 3; ++i) {
134 EXPECT_EQ(data.GetReference(i), array->Get(static_cast<int32_t>(i))) << i;
135 }
136 }
137
138 void RunArrayCopy(Thread* self,
139 ShadowFrame* tmp,
140 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100141 ObjPtr<mirror::ObjectArray<mirror::Object>> src,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700142 int32_t src_pos,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100143 ObjPtr<mirror::ObjectArray<mirror::Object>> dst,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700144 int32_t dst_pos,
145 int32_t length)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700146 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700147 JValue result;
148 tmp->SetVRegReference(0, src);
149 tmp->SetVReg(1, src_pos);
150 tmp->SetVRegReference(2, dst);
151 tmp->SetVReg(3, dst_pos);
152 tmp->SetVReg(4, length);
153 UnstartedSystemArraycopy(self, tmp, &result, 0);
154 bool exception_pending = self->IsExceptionPending();
155 EXPECT_EQ(exception_pending, expect_exception);
156 if (exception_pending) {
157 self->ClearException();
158 }
159 }
160
161 void RunArrayCopy(Thread* self,
162 ShadowFrame* tmp,
163 bool expect_exception,
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100164 ObjPtr<mirror::Class> src_component_class,
165 ObjPtr<mirror::Class> dst_component_class,
Andreas Gampe85a098a2016-03-31 13:30:53 -0700166 const StackHandleScope<3>& src_data,
167 int32_t src_pos,
168 const StackHandleScope<3>& dst_data,
169 int32_t dst_pos,
170 int32_t length,
171 const StackHandleScope<3>& expected_result)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700172 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe85a098a2016-03-31 13:30:53 -0700173 StackHandleScope<3> hs_misc(self);
174 Handle<mirror::Class> dst_component_handle(hs_misc.NewHandle(dst_component_class));
175
176 Handle<mirror::ObjectArray<mirror::Object>> src_handle(
177 hs_misc.NewHandle(CreateObjectArray(self, src_component_class, src_data)));
178
179 Handle<mirror::ObjectArray<mirror::Object>> dst_handle(
180 hs_misc.NewHandle(CreateObjectArray(self, dst_component_handle.Get(), dst_data)));
181
182 RunArrayCopy(self,
183 tmp,
184 expect_exception,
185 src_handle.Get(),
186 src_pos,
187 dst_handle.Get(),
188 dst_pos,
189 length);
190 CheckObjectArray(dst_handle.Get(), expected_result);
191 }
Andreas Gampe89e3b482016-04-12 18:07:36 -0700192
193 void TestCeilFloor(bool ceil,
194 Thread* self,
195 ShadowFrame* tmp,
196 double const test_pairs[][2],
197 size_t num_pairs)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700198 REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe89e3b482016-04-12 18:07:36 -0700199 for (size_t i = 0; i < num_pairs; ++i) {
200 tmp->SetVRegDouble(0, test_pairs[i][0]);
201
202 JValue result;
203 if (ceil) {
204 UnstartedMathCeil(self, tmp, &result, 0);
205 } else {
206 UnstartedMathFloor(self, tmp, &result, 0);
207 }
208
209 ASSERT_FALSE(self->IsExceptionPending());
210
211 // We want precise results.
212 int64_t result_int64t = bit_cast<int64_t, double>(result.GetD());
213 int64_t expect_int64t = bit_cast<int64_t, double>(test_pairs[i][1]);
214 EXPECT_EQ(expect_int64t, result_int64t) << result.GetD() << " vs " << test_pairs[i][1];
215 }
216 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700217
218 // Prepare for aborts. Aborts assume that the exception class is already resolved, as the
219 // loading code doesn't work under transactions.
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700220 void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) {
Vladimir Markoa8bba7d2018-05-30 15:18:48 +0100221 ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass(
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700222 Thread::Current(),
223 Transaction::kAbortExceptionSignature,
224 ScopedNullHandle<mirror::ClassLoader>());
225 CHECK(result != nullptr);
226 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700227};
228
229TEST_F(UnstartedRuntimeTest, MemoryPeekByte) {
230 Thread* self = Thread::Current();
231
232 ScopedObjectAccess soa(self);
233 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
234 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
235 const uint8_t* base_ptr = base_array;
236
237 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700238 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700239
240 for (int32_t i = 0; i < kBaseLen; ++i) {
241 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
242
Andreas Gampedbf54032018-06-18 14:47:01 -0700243 UnstartedMemoryPeekByte(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700244
245 EXPECT_EQ(result.GetB(), static_cast<int8_t>(base_array[i]));
246 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700247}
248
249TEST_F(UnstartedRuntimeTest, MemoryPeekShort) {
250 Thread* self = Thread::Current();
251
252 ScopedObjectAccess soa(self);
253 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
254 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
255 const uint8_t* base_ptr = base_array;
256
257 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700258 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700259
260 int32_t adjusted_length = kBaseLen - sizeof(int16_t);
261 for (int32_t i = 0; i < adjusted_length; ++i) {
262 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
263
Andreas Gampedbf54032018-06-18 14:47:01 -0700264 UnstartedMemoryPeekShort(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700265
Andreas Gampec55bb392018-09-21 00:02:02 +0000266 using unaligned_short __attribute__((__aligned__(1))) = int16_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700267 const unaligned_short* short_ptr = reinterpret_cast<const unaligned_short*>(base_ptr + i);
268 EXPECT_EQ(result.GetS(), *short_ptr);
269 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700270}
271
272TEST_F(UnstartedRuntimeTest, MemoryPeekInt) {
273 Thread* self = Thread::Current();
274
275 ScopedObjectAccess soa(self);
276 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
277 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
278 const uint8_t* base_ptr = base_array;
279
280 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700281 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700282
283 int32_t adjusted_length = kBaseLen - sizeof(int32_t);
284 for (int32_t i = 0; i < adjusted_length; ++i) {
285 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
286
Andreas Gampedbf54032018-06-18 14:47:01 -0700287 UnstartedMemoryPeekInt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700288
Andreas Gampec55bb392018-09-21 00:02:02 +0000289 using unaligned_int __attribute__((__aligned__(1))) = int32_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700290 const unaligned_int* int_ptr = reinterpret_cast<const unaligned_int*>(base_ptr + i);
291 EXPECT_EQ(result.GetI(), *int_ptr);
292 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700293}
294
295TEST_F(UnstartedRuntimeTest, MemoryPeekLong) {
296 Thread* self = Thread::Current();
297
298 ScopedObjectAccess soa(self);
299 constexpr const uint8_t base_array[] = "abcdefghijklmnop";
300 constexpr int32_t kBaseLen = sizeof(base_array) / sizeof(uint8_t);
301 const uint8_t* base_ptr = base_array;
302
303 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700304 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700305
306 int32_t adjusted_length = kBaseLen - sizeof(int64_t);
307 for (int32_t i = 0; i < adjusted_length; ++i) {
308 tmp->SetVRegLong(0, static_cast<int64_t>(reinterpret_cast<intptr_t>(base_ptr + i)));
309
Andreas Gampedbf54032018-06-18 14:47:01 -0700310 UnstartedMemoryPeekLong(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700311
Andreas Gampec55bb392018-09-21 00:02:02 +0000312 using unaligned_long __attribute__((__aligned__(1))) = int64_t;
Andreas Gampe799681b2015-05-15 19:24:12 -0700313 const unaligned_long* long_ptr = reinterpret_cast<const unaligned_long*>(base_ptr + i);
314 EXPECT_EQ(result.GetJ(), *long_ptr);
315 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700316}
317
318TEST_F(UnstartedRuntimeTest, StringGetCharsNoCheck) {
319 Thread* self = Thread::Current();
320
321 ScopedObjectAccess soa(self);
322 StackHandleScope<2> hs(self);
323 // TODO: Actual UTF.
324 constexpr const char base_string[] = "abcdefghijklmnop";
325 Handle<mirror::String> h_test_string(hs.NewHandle(
326 mirror::String::AllocFromModifiedUtf8(self, base_string)));
327 constexpr int32_t kBaseLen = sizeof(base_string) / sizeof(char) - 1;
328 Handle<mirror::CharArray> h_char_array(hs.NewHandle(
329 mirror::CharArray::Alloc(self, kBaseLen)));
330 // A buffer so we can make sure we only modify the elements targetted.
331 uint16_t buf[kBaseLen];
332
333 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700334 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700335
336 for (int32_t start_index = 0; start_index < kBaseLen; ++start_index) {
337 for (int32_t count = 0; count <= kBaseLen; ++count) {
338 for (int32_t trg_offset = 0; trg_offset < kBaseLen; ++trg_offset) {
339 // Only do it when in bounds.
340 if (start_index + count <= kBaseLen && trg_offset + count <= kBaseLen) {
341 tmp->SetVRegReference(0, h_test_string.Get());
342 tmp->SetVReg(1, start_index);
343 tmp->SetVReg(2, count);
344 tmp->SetVRegReference(3, h_char_array.Get());
345 tmp->SetVReg(3, trg_offset);
346
347 // Copy the char_array into buf.
348 memcpy(buf, h_char_array->GetData(), kBaseLen * sizeof(uint16_t));
349
Andreas Gampedbf54032018-06-18 14:47:01 -0700350 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700351
352 uint16_t* data = h_char_array->GetData();
353
354 bool success = true;
355
356 // First segment should be unchanged.
357 for (int32_t i = 0; i < trg_offset; ++i) {
358 success = success && (data[i] == buf[i]);
359 }
360 // Second segment should be a copy.
361 for (int32_t i = trg_offset; i < trg_offset + count; ++i) {
362 success = success && (data[i] == buf[i - trg_offset + start_index]);
363 }
364 // Third segment should be unchanged.
365 for (int32_t i = trg_offset + count; i < kBaseLen; ++i) {
366 success = success && (data[i] == buf[i]);
367 }
368
369 EXPECT_TRUE(success);
370 }
371 }
372 }
373 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700374}
375
376TEST_F(UnstartedRuntimeTest, StringCharAt) {
377 Thread* self = Thread::Current();
378
379 ScopedObjectAccess soa(self);
380 // TODO: Actual UTF.
381 constexpr const char* base_string = "abcdefghijklmnop";
382 int32_t base_len = static_cast<int32_t>(strlen(base_string));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100383 ObjPtr<mirror::String> test_string = mirror::String::AllocFromModifiedUtf8(self, base_string);
Andreas Gampe799681b2015-05-15 19:24:12 -0700384
385 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700386 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700387
388 for (int32_t i = 0; i < base_len; ++i) {
389 tmp->SetVRegReference(0, test_string);
390 tmp->SetVReg(1, i);
391
Andreas Gampedbf54032018-06-18 14:47:01 -0700392 UnstartedStringCharAt(self, tmp.get(), &result, 0);
Andreas Gampe799681b2015-05-15 19:24:12 -0700393
394 EXPECT_EQ(result.GetI(), base_string[i]);
395 }
Andreas Gampe799681b2015-05-15 19:24:12 -0700396}
397
Jeff Hao400ce002015-05-29 10:53:17 -0700398TEST_F(UnstartedRuntimeTest, StringInit) {
399 Thread* self = Thread::Current();
400 ScopedObjectAccess soa(self);
Vladimir Markoacb906d2018-05-30 10:23:49 +0100401 ObjPtr<mirror::Class> klass = GetClassRoot<mirror::String>();
Chang Xingfef27c22017-07-11 09:57:44 -0700402 ArtMethod* method =
Vladimir Markoba118822017-06-12 15:41:56 +0100403 klass->FindConstructor("(Ljava/lang/String;)V",
404 Runtime::Current()->GetClassLinker()->GetImagePointerSize());
405 ASSERT_TRUE(method != nullptr);
Jeff Hao400ce002015-05-29 10:53:17 -0700406
407 // create instruction data for invoke-direct {v0, v1} of method with fake index
408 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Jeff Hao400ce002015-05-29 10:53:17 -0700409
410 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700411 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
Jeff Hao400ce002015-05-29 10:53:17 -0700412 const char* base_string = "hello_world";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100413 StackHandleScope<2> hs(self);
414 Handle<mirror::String> string_arg =
415 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, base_string));
416 Handle<mirror::String> reference_empty_string =
417 hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, ""));
418 shadow_frame->SetVRegReference(0, reference_empty_string.Get());
419 shadow_frame->SetVRegReference(1, string_arg.Get());
Jeff Hao400ce002015-05-29 10:53:17 -0700420
Mathieu Chartier2b2bef22017-10-26 17:10:19 -0700421 interpreter::DoCall<false, false>(method,
422 self,
423 *shadow_frame,
424 Instruction::At(inst_data),
425 inst_data[0],
426 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100427 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Jeff Hao400ce002015-05-29 10:53:17 -0700428 EXPECT_EQ(string_arg->GetLength(), string_result->GetLength());
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700429
430 if (string_arg->IsCompressed() && string_result->IsCompressed()) {
431 EXPECT_EQ(memcmp(string_arg->GetValueCompressed(), string_result->GetValueCompressed(),
432 string_arg->GetLength() * sizeof(uint8_t)), 0);
433 } else if (!string_arg->IsCompressed() && !string_result->IsCompressed()) {
434 EXPECT_EQ(memcmp(string_arg->GetValue(), string_result->GetValue(),
435 string_arg->GetLength() * sizeof(uint16_t)), 0);
436 } else {
437 bool equal = true;
438 for (int i = 0; i < string_arg->GetLength(); ++i) {
439 if (string_arg->CharAt(i) != string_result->CharAt(i)) {
440 equal = false;
441 break;
442 }
443 }
444 EXPECT_EQ(equal, true);
445 }
Jeff Hao400ce002015-05-29 10:53:17 -0700446}
447
Andreas Gampe85a098a2016-03-31 13:30:53 -0700448// Tests the exceptions that should be checked before modifying the destination.
449// (Doesn't check the object vs primitive case ATM.)
450TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTestExceptions) {
451 Thread* self = Thread::Current();
452 ScopedObjectAccess soa(self);
453 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700454 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700455
456 // Note: all tests are not GC safe. Assume there's no GC running here with the few objects we
457 // allocate.
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100458 StackHandleScope<3> hs_misc(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100459 Handle<mirror::Class> object_class(hs_misc.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700460
461 StackHandleScope<3> hs_data(self);
462 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
463 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
464 hs_data.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
465
466 Handle<mirror::ObjectArray<mirror::Object>> array(
467 hs_misc.NewHandle(CreateObjectArray(self, object_class.Get(), hs_data)));
468
Andreas Gampedbf54032018-06-18 14:47:01 -0700469 RunArrayCopy(self, tmp.get(), true, array.Get(), -1, array.Get(), 0, 0);
470 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), -1, 0);
471 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, -1);
472 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 0, 4);
473 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, array.Get(), 1, 3);
474 RunArrayCopy(self, tmp.get(), true, array.Get(), 1, array.Get(), 0, 3);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700475
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100476 Handle<mirror::ObjectArray<mirror::Object>> class_as_array =
477 hs_misc.NewHandle(reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(object_class.Get()));
Andreas Gampedbf54032018-06-18 14:47:01 -0700478 RunArrayCopy(self, tmp.get(), true, class_as_array.Get(), 0, array.Get(), 0, 0);
479 RunArrayCopy(self, tmp.get(), true, array.Get(), 0, class_as_array.Get(), 0, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700480}
481
482TEST_F(UnstartedRuntimeTest, SystemArrayCopyObjectArrayTest) {
483 Thread* self = Thread::Current();
484 ScopedObjectAccess soa(self);
485 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700486 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85a098a2016-03-31 13:30:53 -0700487
488 StackHandleScope<1> hs_object(self);
Vladimir Marko317892b2018-05-31 11:11:32 +0100489 Handle<mirror::Class> object_class(hs_object.NewHandle(GetClassRoot<mirror::Object>()));
Andreas Gampe85a098a2016-03-31 13:30:53 -0700490
491 // Simple test:
492 // [1,2,3]{1 @ 2} into [4,5,6] = [4,2,6]
493 {
494 StackHandleScope<3> hs_src(self);
495 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
496 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
497 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
498
499 StackHandleScope<3> hs_dst(self);
500 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
501 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
502 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
503
504 StackHandleScope<3> hs_expected(self);
505 hs_expected.NewHandle(hs_dst.GetReference(0));
506 hs_expected.NewHandle(hs_dst.GetReference(1));
507 hs_expected.NewHandle(hs_src.GetReference(1));
508
509 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700510 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700511 false,
512 object_class.Get(),
513 object_class.Get(),
514 hs_src,
515 1,
516 hs_dst,
517 2,
518 1,
519 hs_expected);
520 }
521
522 // Simple test:
523 // [1,2,3]{1 @ 1} into [4,5,6] = [4,2,6] (with dst String[])
524 {
525 StackHandleScope<3> hs_src(self);
526 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
527 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "2"));
528 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
529
530 StackHandleScope<3> hs_dst(self);
531 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
532 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
533 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
534
535 StackHandleScope<3> hs_expected(self);
536 hs_expected.NewHandle(hs_dst.GetReference(0));
537 hs_expected.NewHandle(hs_src.GetReference(1));
538 hs_expected.NewHandle(hs_dst.GetReference(2));
539
540 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700541 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700542 false,
543 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100544 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700545 hs_src,
546 1,
547 hs_dst,
548 1,
549 1,
550 hs_expected);
551 }
552
553 // Simple test:
554 // [1,*,3] into [4,5,6] = [1,5,6] + exc
555 {
556 StackHandleScope<3> hs_src(self);
557 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "1"));
Vladimir Markoacb906d2018-05-30 10:23:49 +0100558 hs_src.NewHandle(GetClassRoot<mirror::String>());
Andreas Gampe85a098a2016-03-31 13:30:53 -0700559 hs_src.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "3"));
560
561 StackHandleScope<3> hs_dst(self);
562 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "4"));
563 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "5"));
564 hs_dst.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "6"));
565
566 StackHandleScope<3> hs_expected(self);
567 hs_expected.NewHandle(hs_src.GetReference(0));
568 hs_expected.NewHandle(hs_dst.GetReference(1));
569 hs_expected.NewHandle(hs_dst.GetReference(2));
570
571 RunArrayCopy(self,
Andreas Gampedbf54032018-06-18 14:47:01 -0700572 tmp.get(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700573 true,
574 object_class.Get(),
Vladimir Markoacb906d2018-05-30 10:23:49 +0100575 GetClassRoot<mirror::String>(),
Andreas Gampe85a098a2016-03-31 13:30:53 -0700576 hs_src,
577 0,
578 hs_dst,
579 0,
580 3,
581 hs_expected);
582 }
Andreas Gampe85a098a2016-03-31 13:30:53 -0700583}
584
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700585TEST_F(UnstartedRuntimeTest, IntegerParseIntTest) {
586 Thread* self = Thread::Current();
587 ScopedObjectAccess soa(self);
588
Andreas Gampedbf54032018-06-18 14:47:01 -0700589 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700590
591 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
592 // suffixes).
593 constexpr const char* test_string = "-2147483646";
594 constexpr int32_t test_values[] = {
595 6,
596 46,
597 646,
598 3646,
599 83646,
600 483646,
601 7483646,
602 47483646,
603 147483646,
604 2147483646,
605 -2147483646
606 };
607
608 static_assert(arraysize(test_values) == 11U, "test_values");
609 CHECK_EQ(strlen(test_string), 11U);
610
611 for (size_t i = 0; i <= 10; ++i) {
612 const char* test_value = &test_string[10 - i];
613
614 StackHandleScope<1> hs_str(self);
615 Handle<mirror::String> h_str(
616 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
617 ASSERT_NE(h_str.Get(), nullptr);
618 ASSERT_FALSE(self->IsExceptionPending());
619
620 tmp->SetVRegReference(0, h_str.Get());
621
622 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700623 UnstartedIntegerParseInt(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700624
625 ASSERT_FALSE(self->IsExceptionPending());
626 EXPECT_EQ(result.GetI(), test_values[i]);
627 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700628}
629
630// Right now the same as Integer.Parse
631TEST_F(UnstartedRuntimeTest, LongParseLongTest) {
632 Thread* self = Thread::Current();
633 ScopedObjectAccess soa(self);
634
Andreas Gampedbf54032018-06-18 14:47:01 -0700635 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700636
637 // Test string. Should be valid, and between minimal values of LONG_MIN and LONG_MAX (for all
638 // suffixes).
639 constexpr const char* test_string = "-2147483646";
640 constexpr int64_t test_values[] = {
641 6,
642 46,
643 646,
644 3646,
645 83646,
646 483646,
647 7483646,
648 47483646,
649 147483646,
650 2147483646,
651 -2147483646
652 };
653
654 static_assert(arraysize(test_values) == 11U, "test_values");
655 CHECK_EQ(strlen(test_string), 11U);
656
657 for (size_t i = 0; i <= 10; ++i) {
658 const char* test_value = &test_string[10 - i];
659
660 StackHandleScope<1> hs_str(self);
661 Handle<mirror::String> h_str(
662 hs_str.NewHandle(mirror::String::AllocFromModifiedUtf8(self, test_value)));
663 ASSERT_NE(h_str.Get(), nullptr);
664 ASSERT_FALSE(self->IsExceptionPending());
665
666 tmp->SetVRegReference(0, h_str.Get());
667
668 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700669 UnstartedLongParseLong(self, tmp.get(), &result, 0);
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700670
671 ASSERT_FALSE(self->IsExceptionPending());
672 EXPECT_EQ(result.GetJ(), test_values[i]);
673 }
Andreas Gampe13fc1be2016-04-05 20:14:30 -0700674}
675
Andreas Gampe89e3b482016-04-12 18:07:36 -0700676TEST_F(UnstartedRuntimeTest, Ceil) {
677 Thread* self = Thread::Current();
678 ScopedObjectAccess soa(self);
679
Andreas Gampedbf54032018-06-18 14:47:01 -0700680 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700681
682 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
683 constexpr double inf = std::numeric_limits<double>::infinity();
684 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
685 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
686 constexpr double test_pairs[][2] = {
687 { -0.0, -0.0 },
688 { 0.0, 0.0 },
689 { -0.5, -0.0 },
690 { -1.0, -1.0 },
691 { 0.5, 1.0 },
692 { 1.0, 1.0 },
693 { nan, nan },
694 { inf, inf },
695 { -inf, -inf },
696 { ld1, ld1 },
697 { ld2, ld2 }
698 };
699
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700700 TestCeilFloor(/* ceil= */ true, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700701}
702
703TEST_F(UnstartedRuntimeTest, Floor) {
704 Thread* self = Thread::Current();
705 ScopedObjectAccess soa(self);
706
Andreas Gampedbf54032018-06-18 14:47:01 -0700707 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe89e3b482016-04-12 18:07:36 -0700708
709 constexpr double nan = std::numeric_limits<double>::quiet_NaN();
710 constexpr double inf = std::numeric_limits<double>::infinity();
711 constexpr double ld1 = static_cast<double>((UINT64_C(1) << 53) - 1);
712 constexpr double ld2 = static_cast<double>(UINT64_C(1) << 55);
713 constexpr double test_pairs[][2] = {
714 { -0.0, -0.0 },
715 { 0.0, 0.0 },
716 { -0.5, -1.0 },
717 { -1.0, -1.0 },
718 { 0.5, 0.0 },
719 { 1.0, 1.0 },
720 { nan, nan },
721 { inf, inf },
722 { -inf, -inf },
723 { ld1, ld1 },
724 { ld2, ld2 }
725 };
726
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700727 TestCeilFloor(/* ceil= */ false, self, tmp.get(), test_pairs, arraysize(test_pairs));
Andreas Gampe89e3b482016-04-12 18:07:36 -0700728}
729
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700730TEST_F(UnstartedRuntimeTest, ToLowerUpper) {
731 Thread* self = Thread::Current();
732 ScopedObjectAccess soa(self);
733
Andreas Gampedbf54032018-06-18 14:47:01 -0700734 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700735
736 std::locale c_locale("C");
737
738 // Check ASCII.
739 for (uint32_t i = 0; i < 128; ++i) {
740 bool c_upper = std::isupper(static_cast<char>(i), c_locale);
741 bool c_lower = std::islower(static_cast<char>(i), c_locale);
742 EXPECT_FALSE(c_upper && c_lower) << i;
743
744 // Check toLowerCase.
745 {
746 JValue result;
747 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700748 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700749 ASSERT_FALSE(self->IsExceptionPending());
750 uint32_t lower_result = static_cast<uint32_t>(result.GetI());
751 if (c_lower) {
752 EXPECT_EQ(i, lower_result);
753 } else if (c_upper) {
754 EXPECT_EQ(static_cast<uint32_t>(std::tolower(static_cast<char>(i), c_locale)),
755 lower_result);
756 } else {
757 EXPECT_EQ(i, lower_result);
758 }
759 }
760
761 // Check toUpperCase.
762 {
763 JValue result2;
764 tmp->SetVReg(0, static_cast<int32_t>(i));
Andreas Gampedbf54032018-06-18 14:47:01 -0700765 UnstartedCharacterToUpperCase(self, tmp.get(), &result2, 0);
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700766 ASSERT_FALSE(self->IsExceptionPending());
767 uint32_t upper_result = static_cast<uint32_t>(result2.GetI());
768 if (c_upper) {
769 EXPECT_EQ(i, upper_result);
770 } else if (c_lower) {
771 EXPECT_EQ(static_cast<uint32_t>(std::toupper(static_cast<char>(i), c_locale)),
772 upper_result);
773 } else {
774 EXPECT_EQ(i, upper_result);
775 }
776 }
777 }
778
779 // Check abort for other things. Can't test all.
780
781 PrepareForAborts();
782
783 for (uint32_t i = 128; i < 256; ++i) {
784 {
785 JValue result;
786 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700787 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700788 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700789 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700790 Runtime::Current()->ExitTransactionMode();
791 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700792 }
793 {
794 JValue result;
795 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700796 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700797 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700798 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700799 Runtime::Current()->ExitTransactionMode();
800 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700801 }
802 }
803 for (uint64_t i = 256; i <= std::numeric_limits<uint32_t>::max(); i <<= 1) {
804 {
805 JValue result;
806 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700807 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700808 UnstartedCharacterToLowerCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700809 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700810 Runtime::Current()->ExitTransactionMode();
811 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700812 }
813 {
814 JValue result;
815 tmp->SetVReg(0, static_cast<int32_t>(i));
Chang Xing16d1dd82017-07-20 17:56:26 -0700816 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700817 UnstartedCharacterToUpperCase(self, tmp.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700818 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700819 Runtime::Current()->ExitTransactionMode();
820 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700821 }
822 }
Andreas Gampe8ce9c302016-04-15 21:24:28 -0700823}
824
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700825TEST_F(UnstartedRuntimeTest, Sin) {
826 Thread* self = Thread::Current();
827 ScopedObjectAccess soa(self);
828
Andreas Gampedbf54032018-06-18 14:47:01 -0700829 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700830
831 // Test an important value, PI/6. That's the one we see in practice.
832 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
833 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
834
835 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700836 UnstartedMathSin(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700837
838 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
839 EXPECT_EQ(UINT64_C(0x3fdfffffffffffff), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700840}
841
842TEST_F(UnstartedRuntimeTest, Cos) {
843 Thread* self = Thread::Current();
844 ScopedObjectAccess soa(self);
845
Andreas Gampedbf54032018-06-18 14:47:01 -0700846 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700847
848 // Test an important value, PI/6. That's the one we see in practice.
849 constexpr uint64_t lvalue = UINT64_C(0x3fe0c152382d7365);
850 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue));
851
852 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700853 UnstartedMathCos(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700854
855 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
856 EXPECT_EQ(UINT64_C(0x3febb67ae8584cab), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700857}
858
859TEST_F(UnstartedRuntimeTest, Pow) {
860 Thread* self = Thread::Current();
861 ScopedObjectAccess soa(self);
862
Andreas Gampedbf54032018-06-18 14:47:01 -0700863 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700864
865 // Test an important pair.
866 constexpr uint64_t lvalue1 = UINT64_C(0x4079000000000000);
867 constexpr uint64_t lvalue2 = UINT64_C(0xbfe6db6dc0000000);
868
869 tmp->SetVRegLong(0, static_cast<int64_t>(lvalue1));
870 tmp->SetVRegLong(2, static_cast<int64_t>(lvalue2));
871
872 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700873 UnstartedMathPow(self, tmp.get(), &result, 0);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700874
875 const uint64_t lresult = static_cast<uint64_t>(result.GetJ());
876 EXPECT_EQ(UINT64_C(0x3f8c5c51326aa7ee), lresult);
Andreas Gampeb8a00f92016-04-18 20:51:13 -0700877}
878
Andreas Gampeae78c262017-02-01 20:40:44 -0800879TEST_F(UnstartedRuntimeTest, IsAnonymousClass) {
880 Thread* self = Thread::Current();
881 ScopedObjectAccess soa(self);
882
883 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700884 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800885
Vladimir Marko317892b2018-05-31 11:11:32 +0100886 ObjPtr<mirror::Class> class_klass = GetClassRoot<mirror::Class>();
Andreas Gampeae78c262017-02-01 20:40:44 -0800887 shadow_frame->SetVRegReference(0, class_klass);
Andreas Gampedbf54032018-06-18 14:47:01 -0700888 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800889 EXPECT_EQ(result.GetZ(), 0);
890
891 jobject class_loader = LoadDex("Nested");
892 StackHandleScope<1> hs(soa.Self());
893 Handle<mirror::ClassLoader> loader(
894 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100895 ObjPtr<mirror::Class> c = class_linker_->FindClass(soa.Self(), "LNested$1;", loader);
Andreas Gampeae78c262017-02-01 20:40:44 -0800896 ASSERT_TRUE(c != nullptr);
897 shadow_frame->SetVRegReference(0, c);
Andreas Gampedbf54032018-06-18 14:47:01 -0700898 UnstartedClassIsAnonymousClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800899 EXPECT_EQ(result.GetZ(), 1);
Andreas Gampeae78c262017-02-01 20:40:44 -0800900}
901
902TEST_F(UnstartedRuntimeTest, GetDeclaringClass) {
903 Thread* self = Thread::Current();
904 ScopedObjectAccess soa(self);
905
906 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700907 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800908
909 jobject class_loader = LoadDex("Nested");
910 StackHandleScope<4> hs(self);
911 Handle<mirror::ClassLoader> loader(
912 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)));
913
914 Handle<mirror::Class> nested_klass(hs.NewHandle(
915 class_linker_->FindClass(soa.Self(), "LNested;", loader)));
916 Handle<mirror::Class> inner_klass(hs.NewHandle(
917 class_linker_->FindClass(soa.Self(), "LNested$Inner;", loader)));
918 Handle<mirror::Class> anon_klass(hs.NewHandle(
919 class_linker_->FindClass(soa.Self(), "LNested$1;", loader)));
920
921 shadow_frame->SetVRegReference(0, nested_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700922 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800923 EXPECT_EQ(result.GetL(), nullptr);
924
925 shadow_frame->SetVRegReference(0, inner_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700926 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800927 EXPECT_EQ(result.GetL(), nested_klass.Get());
928
929 shadow_frame->SetVRegReference(0, anon_klass.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700930 UnstartedClassGetDeclaringClass(self, shadow_frame.get(), &result, 0);
Andreas Gampeae78c262017-02-01 20:40:44 -0800931 EXPECT_EQ(result.GetL(), nullptr);
Andreas Gampeae78c262017-02-01 20:40:44 -0800932}
933
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800934TEST_F(UnstartedRuntimeTest, ThreadLocalGet) {
935 Thread* self = Thread::Current();
936 ScopedObjectAccess soa(self);
937
938 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -0700939 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800940
941 StackHandleScope<1> hs(self);
942 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
943
944 // Positive test. See that We get something for float conversion.
945 {
946 Handle<mirror::Class> floating_decimal = hs.NewHandle(
947 class_linker->FindClass(self,
948 "Lsun/misc/FloatingDecimal;",
949 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -0800950 ASSERT_TRUE(floating_decimal != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800951 ASSERT_TRUE(class_linker->EnsureInitialized(self, floating_decimal, true, true));
952
Vladimir Markoba118822017-06-12 15:41:56 +0100953 ArtMethod* caller_method = floating_decimal->FindClassMethod(
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800954 "getBinaryToASCIIBuffer",
955 "()Lsun/misc/FloatingDecimal$BinaryToASCIIBuffer;",
956 class_linker->GetImagePointerSize());
957 // floating_decimal->DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
958 ASSERT_TRUE(caller_method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +0100959 ASSERT_TRUE(caller_method->IsDirect());
960 ASSERT_TRUE(caller_method->GetDeclaringClass() == floating_decimal.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -0700961 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
962 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800963
Andreas Gampedbf54032018-06-18 14:47:01 -0700964 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800965 EXPECT_TRUE(result.GetL() != nullptr);
966 EXPECT_FALSE(self->IsExceptionPending());
967
Andreas Gampedbf54032018-06-18 14:47:01 -0700968 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800969 }
970
971 // Negative test.
972 PrepareForAborts();
973
974 {
975 // Just use a method in Class.
Vladimir Marko317892b2018-05-31 11:11:32 +0100976 ObjPtr<mirror::Class> class_class = GetClassRoot<mirror::Class>();
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800977 ArtMethod* caller_method =
978 &*class_class->GetDeclaredMethods(class_linker->GetImagePointerSize()).begin();
Andreas Gampedbf54032018-06-18 14:47:01 -0700979 UniqueDeoptShadowFramePtr caller_frame = CreateShadowFrame(10, nullptr, caller_method, 0);
980 shadow_frame->SetLink(caller_frame.get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800981
Chang Xing16d1dd82017-07-20 17:56:26 -0700982 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -0700983 UnstartedThreadLocalGet(self, shadow_frame.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -0700984 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800985 Runtime::Current()->ExitTransactionMode();
986 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800987 self->ClearException();
988
Andreas Gampedbf54032018-06-18 14:47:01 -0700989 shadow_frame->SetLink(nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800990 }
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -0800991}
992
993TEST_F(UnstartedRuntimeTest, FloatConversion) {
994 Thread* self = Thread::Current();
995 ScopedObjectAccess soa(self);
996
997 StackHandleScope<1> hs(self);
998 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
999 Handle<mirror::Class> double_class = hs.NewHandle(
1000 class_linker->FindClass(self,
1001 "Ljava/lang/Double;",
1002 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampefa4333d2017-02-14 11:10:34 -08001003 ASSERT_TRUE(double_class != nullptr);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001004 ASSERT_TRUE(class_linker->EnsureInitialized(self, double_class, true, true));
1005
Vladimir Markoba118822017-06-12 15:41:56 +01001006 ArtMethod* method = double_class->FindClassMethod("toString",
1007 "(D)Ljava/lang/String;",
1008 class_linker->GetImagePointerSize());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001009 ASSERT_TRUE(method != nullptr);
Vladimir Markoba118822017-06-12 15:41:56 +01001010 ASSERT_TRUE(method->IsDirect());
1011 ASSERT_TRUE(method->GetDeclaringClass() == double_class.Get());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001012
1013 // create instruction data for invoke-direct {v0, v1} of method with fake index
1014 uint16_t inst_data[3] = { 0x2070, 0x0000, 0x0010 };
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001015
1016 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001017 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, method, 0);
1018
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001019 shadow_frame->SetVRegDouble(0, 1.23);
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001020 interpreter::DoCall<false, false>(method,
1021 self,
1022 *shadow_frame,
1023 Instruction::At(inst_data),
1024 inst_data[0],
1025 &result);
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001026 ObjPtr<mirror::String> string_result = down_cast<mirror::String*>(result.GetL());
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001027 ASSERT_TRUE(string_result != nullptr);
1028
1029 std::string mod_utf = string_result->ToModifiedUtf8();
1030 EXPECT_EQ("1.23", mod_utf);
Andreas Gampe3d2fcaa2017-02-09 12:50:52 -08001031}
1032
Andreas Gampebad529d2017-02-13 18:52:10 -08001033TEST_F(UnstartedRuntimeTest, ThreadCurrentThread) {
1034 Thread* self = Thread::Current();
1035 ScopedObjectAccess soa(self);
1036
1037 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001038 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampebad529d2017-02-13 18:52:10 -08001039
1040 StackHandleScope<1> hs(self);
1041 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1042 Handle<mirror::Class> thread_class = hs.NewHandle(
1043 class_linker->FindClass(self, "Ljava/lang/Thread;", ScopedNullHandle<mirror::ClassLoader>()));
1044 ASSERT_TRUE(thread_class.Get() != nullptr);
1045 ASSERT_TRUE(class_linker->EnsureInitialized(self, thread_class, true, true));
1046
1047 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1048 // be recreated at runtime).
1049 PrepareForAborts();
1050
1051 {
Chang Xing16d1dd82017-07-20 17:56:26 -07001052 Runtime::Current()->EnterTransactionMode();
Andreas Gampedbf54032018-06-18 14:47:01 -07001053 UnstartedThreadCurrentThread(self, shadow_frame.get(), &result, 0);
Chang Xing16d1dd82017-07-20 17:56:26 -07001054 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampebad529d2017-02-13 18:52:10 -08001055 Runtime::Current()->ExitTransactionMode();
1056 ASSERT_TRUE(self->IsExceptionPending());
Andreas Gampebad529d2017-02-13 18:52:10 -08001057 self->ClearException();
1058 }
Andreas Gampebad529d2017-02-13 18:52:10 -08001059}
1060
1061TEST_F(UnstartedRuntimeTest, LogManager) {
1062 Thread* self = Thread::Current();
1063 ScopedObjectAccess soa(self);
1064
1065 StackHandleScope<1> hs(self);
1066 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1067 Handle<mirror::Class> log_manager_class = hs.NewHandle(
Andreas Gampe9486a162017-02-16 15:17:47 -08001068 class_linker->FindClass(self,
1069 "Ljava/util/logging/LogManager;",
1070 ScopedNullHandle<mirror::ClassLoader>()));
Andreas Gampebad529d2017-02-13 18:52:10 -08001071 ASSERT_TRUE(log_manager_class.Get() != nullptr);
1072 ASSERT_TRUE(class_linker->EnsureInitialized(self, log_manager_class, true, true));
1073}
1074
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001075class UnstartedClassForNameTest : public UnstartedRuntimeTest {
1076 public:
1077 template <typename T>
1078 void RunTest(T& runner, bool in_transaction, bool should_succeed) {
1079 Thread* self = Thread::Current();
1080 ScopedObjectAccess soa(self);
1081
1082 // Ensure that Class is initialized.
1083 {
1084 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1085 StackHandleScope<1> hs(self);
Vladimir Marko317892b2018-05-31 11:11:32 +01001086 Handle<mirror::Class> h_class = hs.NewHandle(GetClassRoot<mirror::Class>());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001087 CHECK(class_linker->EnsureInitialized(self, h_class, true, true));
1088 }
1089
1090 // A selection of classes from different core classpath components.
1091 constexpr const char* kTestCases[] = {
1092 "java.net.CookieManager", // From libcore.
1093 "dalvik.system.ClassExt", // From libart.
1094 };
1095
1096 if (in_transaction) {
1097 // For transaction mode, we cannot load any classes, as the pre-fence initialization of
1098 // classes isn't transactional. Load them ahead of time.
1099 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1100 for (const char* name : kTestCases) {
1101 class_linker->FindClass(self,
1102 DotToDescriptor(name).c_str(),
1103 ScopedNullHandle<mirror::ClassLoader>());
1104 CHECK(!self->IsExceptionPending()) << self->GetException()->Dump();
1105 }
1106 }
1107
1108 if (!should_succeed) {
1109 // Negative test. In general, currentThread should fail (as we should not leak a peer that will
1110 // be recreated at runtime).
1111 PrepareForAborts();
1112 }
1113
1114 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001115 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001116
1117 for (const char* name : kTestCases) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001118 ObjPtr<mirror::String> name_string = mirror::String::AllocFromModifiedUtf8(self, name);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001119 CHECK(name_string != nullptr);
1120
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001121 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001122 Runtime::Current()->EnterTransactionMode();
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001123 }
1124 CHECK(!self->IsExceptionPending());
1125
Andreas Gampedbf54032018-06-18 14:47:01 -07001126 runner(self, shadow_frame.get(), name_string, &result);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001127
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001128 if (should_succeed) {
1129 CHECK(!self->IsExceptionPending()) << name << " " << self->GetException()->Dump();
1130 CHECK(result.GetL() != nullptr) << name;
1131 } else {
1132 CHECK(self->IsExceptionPending()) << name;
1133 if (in_transaction) {
Chang Xing16d1dd82017-07-20 17:56:26 -07001134 ASSERT_TRUE(Runtime::Current()->IsTransactionAborted());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001135 }
1136 self->ClearException();
1137 }
Chang Xing16d1dd82017-07-20 17:56:26 -07001138
1139 if (in_transaction) {
1140 Runtime::Current()->ExitTransactionMode();
1141 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001142 }
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001143 }
1144
1145 mirror::ClassLoader* GetBootClassLoader() REQUIRES_SHARED(Locks::mutator_lock_) {
1146 Thread* self = Thread::Current();
1147 StackHandleScope<2> hs(self);
1148 MutableHandle<mirror::ClassLoader> boot_cp = hs.NewHandle<mirror::ClassLoader>(nullptr);
1149
1150 {
1151 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1152
1153 // Create the fake boot classloader. Any instance is fine, they are technically interchangeable.
1154 Handle<mirror::Class> boot_cp_class = hs.NewHandle(
1155 class_linker->FindClass(self,
1156 "Ljava/lang/BootClassLoader;",
1157 ScopedNullHandle<mirror::ClassLoader>()));
1158 CHECK(boot_cp_class != nullptr);
1159 CHECK(class_linker->EnsureInitialized(self, boot_cp_class, true, true));
1160
1161 boot_cp.Assign(boot_cp_class->AllocObject(self)->AsClassLoader());
1162 CHECK(boot_cp != nullptr);
1163
Vladimir Markoba118822017-06-12 15:41:56 +01001164 ArtMethod* boot_cp_init = boot_cp_class->FindConstructor(
1165 "()V", class_linker->GetImagePointerSize());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001166 CHECK(boot_cp_init != nullptr);
1167
1168 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001169 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, boot_cp_init, 0);
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001170 shadow_frame->SetVRegReference(0, boot_cp.Get());
1171
1172 // create instruction data for invoke-direct {v0} of method with fake index
1173 uint16_t inst_data[3] = { 0x1070, 0x0000, 0x0010 };
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001174
1175 interpreter::DoCall<false, false>(boot_cp_init,
1176 self,
1177 *shadow_frame,
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001178 Instruction::At(inst_data),
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001179 inst_data[0],
1180 &result);
1181 CHECK(!self->IsExceptionPending());
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001182 }
1183
1184 return boot_cp.Get();
1185 }
1186};
1187
1188TEST_F(UnstartedClassForNameTest, ClassForName) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001189 auto runner = [](Thread* self,
1190 ShadowFrame* shadow_frame,
1191 ObjPtr<mirror::String> name,
1192 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001193 shadow_frame->SetVRegReference(0, name);
1194 UnstartedClassForName(self, shadow_frame, result, 0);
1195 };
1196 RunTest(runner, false, true);
1197}
1198
1199TEST_F(UnstartedClassForNameTest, ClassForNameLong) {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001200 auto runner = [](Thread* self,
1201 ShadowFrame* shadow_frame,
1202 ObjPtr<mirror::String> name,
1203 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001204 shadow_frame->SetVRegReference(0, name);
1205 shadow_frame->SetVReg(1, 0);
1206 shadow_frame->SetVRegReference(2, nullptr);
1207 UnstartedClassForNameLong(self, shadow_frame, result, 0);
1208 };
1209 RunTest(runner, false, true);
1210}
1211
1212TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoader) {
1213 Thread* self = Thread::Current();
1214 ScopedObjectAccess soa(self);
1215
1216 StackHandleScope<1> hs(self);
1217 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1218
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001219 auto runner = [&](Thread* th,
1220 ShadowFrame* shadow_frame,
1221 ObjPtr<mirror::String> name,
1222 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001223 shadow_frame->SetVRegReference(0, name);
1224 shadow_frame->SetVReg(1, 0);
1225 shadow_frame->SetVRegReference(2, boot_cp.Get());
1226 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1227 };
1228 RunTest(runner, false, true);
1229}
1230
1231TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderTransaction) {
1232 Thread* self = Thread::Current();
1233 ScopedObjectAccess soa(self);
1234
1235 StackHandleScope<1> hs(self);
1236 Handle<mirror::ClassLoader> boot_cp = hs.NewHandle(GetBootClassLoader());
1237
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001238 auto runner = [&](Thread* th,
1239 ShadowFrame* shadow_frame,
1240 ObjPtr<mirror::String> name,
1241 JValue* result)
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001242 REQUIRES_SHARED(Locks::mutator_lock_) {
1243 shadow_frame->SetVRegReference(0, name);
1244 shadow_frame->SetVReg(1, 0);
1245 shadow_frame->SetVRegReference(2, boot_cp.Get());
1246 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1247 };
1248 RunTest(runner, true, true);
1249}
1250
1251TEST_F(UnstartedClassForNameTest, ClassForNameLongWithClassLoaderFail) {
1252 Thread* self = Thread::Current();
1253 ScopedObjectAccess soa(self);
1254
1255 StackHandleScope<2> hs(self);
1256 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1257 jobject path_jobj = class_linker->CreatePathClassLoader(self, {});
1258 ASSERT_TRUE(path_jobj != nullptr);
1259 Handle<mirror::ClassLoader> path_cp = hs.NewHandle<mirror::ClassLoader>(
1260 self->DecodeJObject(path_jobj)->AsClassLoader());
1261
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001262 auto runner = [&](Thread* th,
1263 ShadowFrame* shadow_frame,
1264 ObjPtr<mirror::String> name,
1265 JValue* result) REQUIRES_SHARED(Locks::mutator_lock_) {
Andreas Gampe47de0fa2017-02-15 19:29:36 -08001266 shadow_frame->SetVRegReference(0, name);
1267 shadow_frame->SetVReg(1, 0);
1268 shadow_frame->SetVRegReference(2, path_cp.Get());
1269 UnstartedClassForNameLong(th, shadow_frame, result, 0);
1270 };
1271 RunTest(runner, true, false);
1272}
1273
Andreas Gampe9486a162017-02-16 15:17:47 -08001274TEST_F(UnstartedRuntimeTest, ClassGetSignatureAnnotation) {
1275 Thread* self = Thread::Current();
1276 ScopedObjectAccess soa(self);
1277
1278 StackHandleScope<1> hs(self);
1279 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1280 Handle<mirror::Class> list_class = hs.NewHandle(
1281 class_linker->FindClass(self,
1282 "Ljava/util/List;",
1283 ScopedNullHandle<mirror::ClassLoader>()));
1284 ASSERT_TRUE(list_class.Get() != nullptr);
1285 ASSERT_TRUE(class_linker->EnsureInitialized(self, list_class, true, true));
1286
1287 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001288 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001289
1290 shadow_frame->SetVRegReference(0, list_class.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001291 UnstartedClassGetSignatureAnnotation(self, shadow_frame.get(), &result, 0);
Andreas Gampe9486a162017-02-16 15:17:47 -08001292 ASSERT_TRUE(result.GetL() != nullptr);
1293 ASSERT_FALSE(self->IsExceptionPending());
1294
Andreas Gampe9486a162017-02-16 15:17:47 -08001295 ASSERT_TRUE(result.GetL()->IsObjectArray());
1296 ObjPtr<mirror::ObjectArray<mirror::Object>> array =
1297 result.GetL()->AsObjectArray<mirror::Object>();
1298 std::ostringstream oss;
1299 for (int32_t i = 0; i != array->GetLength(); ++i) {
1300 ObjPtr<mirror::Object> elem = array->Get(i);
1301 ASSERT_TRUE(elem != nullptr);
1302 ASSERT_TRUE(elem->IsString());
1303 oss << elem->AsString()->ToModifiedUtf8();
1304 }
1305 std::string output_string = oss.str();
1306 ASSERT_EQ(output_string, "<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;");
1307}
1308
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001309TEST_F(UnstartedRuntimeTest, ConstructorNewInstance0) {
1310 Thread* self = Thread::Current();
1311 ScopedObjectAccess soa(self);
1312
1313 StackHandleScope<4> hs(self);
1314 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1315
1316 // Get Throwable.
Vladimir Markoadbceb72018-05-29 14:34:14 +01001317 Handle<mirror::Class> throw_class = hs.NewHandle(GetClassRoot<mirror::Throwable>());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001318 ASSERT_TRUE(class_linker->EnsureInitialized(self, throw_class, true, true));
1319
1320 // Get an input object.
1321 Handle<mirror::String> input = hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, "abd"));
1322
1323 // Find the constructor.
Vladimir Markoba118822017-06-12 15:41:56 +01001324 ArtMethod* throw_cons = throw_class->FindConstructor(
1325 "(Ljava/lang/String;)V", class_linker->GetImagePointerSize());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001326 ASSERT_TRUE(throw_cons != nullptr);
Chang Xingfef27c22017-07-11 09:57:44 -07001327 Handle<mirror::Constructor> cons;
1328 if (class_linker->GetImagePointerSize() == PointerSize::k64) {
1329 cons = hs.NewHandle(
1330 mirror::Constructor::CreateFromArtMethod<PointerSize::k64, false>(self, throw_cons));
1331 ASSERT_TRUE(cons != nullptr);
1332 } else {
1333 cons = hs.NewHandle(
1334 mirror::Constructor::CreateFromArtMethod<PointerSize::k32, false>(self, throw_cons));
1335 ASSERT_TRUE(cons != nullptr);
1336 }
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001337
1338 Handle<mirror::ObjectArray<mirror::Object>> args = hs.NewHandle(
Andreas Gampec6ea7d02017-02-01 16:46:28 -08001339 mirror::ObjectArray<mirror::Object>::Alloc(
Vladimir Markob4eb1b12018-05-24 11:09:38 +01001340 self, GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker_), 1));
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001341 ASSERT_TRUE(args != nullptr);
1342 args->Set(0, input.Get());
1343
1344 // OK, we're ready now.
1345 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001346 UniqueDeoptShadowFramePtr shadow_frame = CreateShadowFrame(10, nullptr, nullptr, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001347 shadow_frame->SetVRegReference(0, cons.Get());
1348 shadow_frame->SetVRegReference(1, args.Get());
Andreas Gampedbf54032018-06-18 14:47:01 -07001349 UnstartedConstructorNewInstance0(self, shadow_frame.get(), &result, 0);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001350
1351 ASSERT_TRUE(result.GetL() != nullptr);
1352 ASSERT_FALSE(self->IsExceptionPending());
1353
1354 // Should be a new object.
1355 ASSERT_NE(result.GetL(), input.Get());
Vladimir Markoadbceb72018-05-29 14:34:14 +01001356 // Should be of type Throwable.
1357 ASSERT_OBJ_PTR_EQ(GetClassRoot<mirror::Throwable>(), result.GetL()->GetClass());
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001358 // Should have the right string.
1359 ObjPtr<mirror::String> result_msg =
1360 reinterpret_cast<mirror::Throwable*>(result.GetL())->GetDetailMessage();
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001361 EXPECT_OBJ_PTR_EQ(input.Get(), result_msg);
Andreas Gampe85bef7e2017-02-16 18:13:26 -08001362}
1363
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001364TEST_F(UnstartedRuntimeTest, IdentityHashCode) {
1365 Thread* self = Thread::Current();
1366 ScopedObjectAccess soa(self);
Andreas Gampedbf54032018-06-18 14:47:01 -07001367 UniqueDeoptShadowFramePtr tmp = CreateShadowFrame(10, nullptr, nullptr, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001368
1369 JValue result;
Andreas Gampedbf54032018-06-18 14:47:01 -07001370 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001371
1372 EXPECT_EQ(0, result.GetI());
1373 ASSERT_FALSE(self->IsExceptionPending());
1374
1375 ObjPtr<mirror::String> str = mirror::String::AllocFromModifiedUtf8(self, "abd");
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +01001376 tmp->SetVRegReference(0, str);
Andreas Gampedbf54032018-06-18 14:47:01 -07001377 UnstartedSystemIdentityHashCode(self, tmp.get(), &result, 0);
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001378 EXPECT_NE(0, result.GetI());
1379 EXPECT_EQ(str->IdentityHashCode(), result.GetI());
1380 ASSERT_FALSE(self->IsExceptionPending());
Nicolas Geoffrayece2f7c2017-03-08 16:11:23 +00001381}
1382
Andreas Gampe799681b2015-05-15 19:24:12 -07001383} // namespace interpreter
1384} // namespace art