blob: dcfa24bea100a887dfe5ba789a2ff5e257939907 [file] [log] [blame]
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001/*
2 * Copyright (C) 2014 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 "common_test.h"
18#include "invoke_arg_array_builder.h"
19#include "mirror/array-inl.h"
20#include "mirror/art_field-inl.h"
21#include "mirror/art_method-inl.h"
22#include "transaction.h"
23
24namespace art {
25
26class TransactionTest : public CommonTest {
27};
28
29TEST_F(TransactionTest, Object_class) {
30 ScopedObjectAccess soa(Thread::Current());
31 SirtRef<mirror::Class> sirt_klass(soa.Self(),
32 class_linker_->FindSystemClass("Ljava/lang/Object;"));
33 ASSERT_TRUE(sirt_klass.get() != nullptr);
34
35 Transaction transaction;
36 Runtime::Current()->EnterTransactionMode(&transaction);
37 SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
38 ASSERT_TRUE(sirt_obj.get() != nullptr);
39 ASSERT_EQ(sirt_obj->GetClass(), sirt_klass.get());
40 Runtime::Current()->ExitTransactionMode();
41
42 // Aborting transaction must not clear the Object::class field.
43 transaction.Abort();
44 EXPECT_EQ(sirt_obj->GetClass(), sirt_klass.get());
45}
46
47TEST_F(TransactionTest, Object_monitor) {
48 ScopedObjectAccess soa(Thread::Current());
49 SirtRef<mirror::Class> sirt_klass(soa.Self(),
50 class_linker_->FindSystemClass("Ljava/lang/Object;"));
51 ASSERT_TRUE(sirt_klass.get() != nullptr);
52 SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
53 ASSERT_TRUE(sirt_obj.get() != nullptr);
54 ASSERT_EQ(sirt_obj->GetClass(), sirt_klass.get());
55
56 // Lock object's monitor outside the transaction.
57 sirt_obj->MonitorEnter(soa.Self());
58 uint32_t old_lock_word = sirt_obj->GetLockWord().GetValue();
59
60 Transaction transaction;
61 Runtime::Current()->EnterTransactionMode(&transaction);
62 // Unlock object's monitor inside the transaction.
63 sirt_obj->MonitorExit(soa.Self());
64 uint32_t new_lock_word = sirt_obj->GetLockWord().GetValue();
65 Runtime::Current()->ExitTransactionMode();
66
67 // Aborting transaction must not clear the Object::class field.
68 transaction.Abort();
69 uint32_t aborted_lock_word = sirt_obj->GetLockWord().GetValue();
70 EXPECT_NE(old_lock_word, new_lock_word);
71 EXPECT_EQ(aborted_lock_word, new_lock_word);
72}
73
74TEST_F(TransactionTest, Array_length) {
75 ScopedObjectAccess soa(Thread::Current());
76 SirtRef<mirror::Class> sirt_klass(soa.Self(),
77 class_linker_->FindSystemClass("[Ljava/lang/Object;"));
78 ASSERT_TRUE(sirt_klass.get() != nullptr);
79
80 constexpr int32_t kArraySize = 2;
81
82 Transaction transaction;
83 Runtime::Current()->EnterTransactionMode(&transaction);
84
85 // Allocate an array during transaction.
86 SirtRef<mirror::Array> sirt_obj(soa.Self(),
87 mirror::Array::Alloc<false>(soa.Self(), sirt_klass.get(), kArraySize));
88 ASSERT_TRUE(sirt_obj.get() != nullptr);
89 ASSERT_EQ(sirt_obj->GetClass(), sirt_klass.get());
90 Runtime::Current()->ExitTransactionMode();
91
92 // Aborting transaction must not clear the Object::class field.
93 transaction.Abort();
94 EXPECT_EQ(sirt_obj->GetLength(), kArraySize);
95}
96
97TEST_F(TransactionTest, StaticFieldsTest) {
98 ScopedObjectAccess soa(Thread::Current());
99 SirtRef<mirror::ClassLoader> class_loader(
100 soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")));
101 ASSERT_TRUE(class_loader.get() != nullptr);
102
103 SirtRef<mirror::Class> sirt_klass(soa.Self(),
104 class_linker_->FindClass("LStaticFieldsTest;", class_loader));
105 ASSERT_TRUE(sirt_klass.get() != nullptr);
106 class_linker_->EnsureInitialized(sirt_klass, true, true);
107 ASSERT_TRUE(sirt_klass->IsInitialized());
108
109 // Lookup fields.
110 mirror::ArtField* booleanField = sirt_klass->FindDeclaredStaticField("booleanField", "Z");
111 ASSERT_TRUE(booleanField != nullptr);
112 ASSERT_EQ(FieldHelper(booleanField).GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
113 ASSERT_EQ(booleanField->GetBoolean(sirt_klass.get()), false);
114
115 mirror::ArtField* byteField = sirt_klass->FindDeclaredStaticField("byteField", "B");
116 ASSERT_TRUE(byteField != nullptr);
117 ASSERT_EQ(FieldHelper(byteField).GetTypeAsPrimitiveType(), Primitive::kPrimByte);
118 ASSERT_EQ(byteField->GetByte(sirt_klass.get()), 0);
119
120 mirror::ArtField* charField = sirt_klass->FindDeclaredStaticField("charField", "C");
121 ASSERT_TRUE(charField != nullptr);
122 ASSERT_EQ(FieldHelper(charField).GetTypeAsPrimitiveType(), Primitive::kPrimChar);
123 ASSERT_EQ(charField->GetChar(sirt_klass.get()), 0u);
124
125 mirror::ArtField* shortField = sirt_klass->FindDeclaredStaticField("shortField", "S");
126 ASSERT_TRUE(shortField != nullptr);
127 ASSERT_EQ(FieldHelper(shortField).GetTypeAsPrimitiveType(), Primitive::kPrimShort);
128 ASSERT_EQ(shortField->GetShort(sirt_klass.get()), 0);
129
130 mirror::ArtField* intField = sirt_klass->FindDeclaredStaticField("intField", "I");
131 ASSERT_TRUE(intField != nullptr);
132 ASSERT_EQ(FieldHelper(intField).GetTypeAsPrimitiveType(), Primitive::kPrimInt);
133 ASSERT_EQ(intField->GetInt(sirt_klass.get()), 0);
134
135 mirror::ArtField* longField = sirt_klass->FindDeclaredStaticField("longField", "J");
136 ASSERT_TRUE(longField != nullptr);
137 ASSERT_EQ(FieldHelper(longField).GetTypeAsPrimitiveType(), Primitive::kPrimLong);
138 ASSERT_EQ(longField->GetLong(sirt_klass.get()), static_cast<int64_t>(0));
139
140 mirror::ArtField* floatField = sirt_klass->FindDeclaredStaticField("floatField", "F");
141 ASSERT_TRUE(floatField != nullptr);
142 ASSERT_EQ(FieldHelper(floatField).GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
143 ASSERT_EQ(floatField->GetFloat(sirt_klass.get()), static_cast<float>(0.0f));
144
145 mirror::ArtField* doubleField = sirt_klass->FindDeclaredStaticField("doubleField", "D");
146 ASSERT_TRUE(doubleField != nullptr);
147 ASSERT_EQ(FieldHelper(doubleField).GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
148 ASSERT_EQ(doubleField->GetDouble(sirt_klass.get()), static_cast<double>(0.0));
149
150 mirror::ArtField* objectField = sirt_klass->FindDeclaredStaticField("objectField", "Ljava/lang/Object;");
151 ASSERT_TRUE(objectField != nullptr);
152 ASSERT_EQ(FieldHelper(objectField).GetTypeAsPrimitiveType(), Primitive::kPrimNot);
153 ASSERT_EQ(objectField->GetObject(sirt_klass.get()), nullptr);
154
155 // Create a java.lang.Object instance to set objectField.
156 SirtRef<mirror::Class> object_klass(soa.Self(), class_linker_->FindSystemClass("Ljava/lang/Object;"));
157 ASSERT_TRUE(object_klass.get() != nullptr);
158 SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
159 ASSERT_TRUE(sirt_obj.get() != nullptr);
160 ASSERT_EQ(sirt_obj->GetClass(), sirt_klass.get());
161
162 // Modify fields inside transaction and abort it.
163 Transaction transaction;
164 Runtime::Current()->EnterTransactionMode(&transaction);
165 booleanField->SetBoolean<true>(sirt_klass.get(), true);
166 byteField->SetByte<true>(sirt_klass.get(), 1);
167 charField->SetChar<true>(sirt_klass.get(), 1u);
168 shortField->SetShort<true>(sirt_klass.get(), 1);
169 intField->SetInt<true>(sirt_klass.get(), 1);
170 longField->SetLong<true>(sirt_klass.get(), 1);
171 floatField->SetFloat<true>(sirt_klass.get(), 1.0);
172 doubleField->SetDouble<true>(sirt_klass.get(), 1.0);
173 objectField->SetObject<true>(sirt_klass.get(), sirt_obj.get());
174 Runtime::Current()->ExitTransactionMode();
175 transaction.Abort();
176
177 // Check values have properly been restored to their original (default) value.
178 EXPECT_EQ(booleanField->GetBoolean(sirt_klass.get()), false);
179 EXPECT_EQ(byteField->GetByte(sirt_klass.get()), 0);
180 EXPECT_EQ(charField->GetChar(sirt_klass.get()), 0u);
181 EXPECT_EQ(shortField->GetShort(sirt_klass.get()), 0);
182 EXPECT_EQ(intField->GetInt(sirt_klass.get()), 0);
183 EXPECT_EQ(longField->GetLong(sirt_klass.get()), static_cast<int64_t>(0));
184 EXPECT_EQ(floatField->GetFloat(sirt_klass.get()), static_cast<float>(0.0f));
185 EXPECT_EQ(doubleField->GetDouble(sirt_klass.get()), static_cast<double>(0.0));
186 EXPECT_EQ(objectField->GetObject(sirt_klass.get()), nullptr);
187}
188
189TEST_F(TransactionTest, InstanceFieldsTest) {
190 ScopedObjectAccess soa(Thread::Current());
191 SirtRef<mirror::ClassLoader> class_loader(
192 soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")));
193 ASSERT_TRUE(class_loader.get() != nullptr);
194
195 SirtRef<mirror::Class> sirt_klass(soa.Self(),
196 class_linker_->FindClass("LInstanceFieldsTest;", class_loader));
197 ASSERT_TRUE(sirt_klass.get() != nullptr);
198 class_linker_->EnsureInitialized(sirt_klass, true, true);
199 ASSERT_TRUE(sirt_klass->IsInitialized());
200
201 // Allocate an InstanceFieldTest object.
202 SirtRef<mirror::Object> sirt_instance(soa.Self(), sirt_klass->AllocObject(soa.Self()));
203 ASSERT_TRUE(sirt_instance.get() != nullptr);
204
205 // Lookup fields.
206 mirror::ArtField* booleanField = sirt_klass->FindDeclaredInstanceField("booleanField", "Z");
207 ASSERT_TRUE(booleanField != nullptr);
208 ASSERT_EQ(FieldHelper(booleanField).GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
209 ASSERT_EQ(booleanField->GetBoolean(sirt_instance.get()), false);
210
211 mirror::ArtField* byteField = sirt_klass->FindDeclaredInstanceField("byteField", "B");
212 ASSERT_TRUE(byteField != nullptr);
213 ASSERT_EQ(FieldHelper(byteField).GetTypeAsPrimitiveType(), Primitive::kPrimByte);
214 ASSERT_EQ(byteField->GetByte(sirt_instance.get()), 0);
215
216 mirror::ArtField* charField = sirt_klass->FindDeclaredInstanceField("charField", "C");
217 ASSERT_TRUE(charField != nullptr);
218 ASSERT_EQ(FieldHelper(charField).GetTypeAsPrimitiveType(), Primitive::kPrimChar);
219 ASSERT_EQ(charField->GetChar(sirt_instance.get()), 0u);
220
221 mirror::ArtField* shortField = sirt_klass->FindDeclaredInstanceField("shortField", "S");
222 ASSERT_TRUE(shortField != nullptr);
223 ASSERT_EQ(FieldHelper(shortField).GetTypeAsPrimitiveType(), Primitive::kPrimShort);
224 ASSERT_EQ(shortField->GetShort(sirt_instance.get()), 0);
225
226 mirror::ArtField* intField = sirt_klass->FindDeclaredInstanceField("intField", "I");
227 ASSERT_TRUE(intField != nullptr);
228 ASSERT_EQ(FieldHelper(intField).GetTypeAsPrimitiveType(), Primitive::kPrimInt);
229 ASSERT_EQ(intField->GetInt(sirt_instance.get()), 0);
230
231 mirror::ArtField* longField = sirt_klass->FindDeclaredInstanceField("longField", "J");
232 ASSERT_TRUE(longField != nullptr);
233 ASSERT_EQ(FieldHelper(longField).GetTypeAsPrimitiveType(), Primitive::kPrimLong);
234 ASSERT_EQ(longField->GetLong(sirt_instance.get()), static_cast<int64_t>(0));
235
236 mirror::ArtField* floatField = sirt_klass->FindDeclaredInstanceField("floatField", "F");
237 ASSERT_TRUE(floatField != nullptr);
238 ASSERT_EQ(FieldHelper(floatField).GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
239 ASSERT_EQ(floatField->GetFloat(sirt_instance.get()), static_cast<float>(0.0f));
240
241 mirror::ArtField* doubleField = sirt_klass->FindDeclaredInstanceField("doubleField", "D");
242 ASSERT_TRUE(doubleField != nullptr);
243 ASSERT_EQ(FieldHelper(doubleField).GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
244 ASSERT_EQ(doubleField->GetDouble(sirt_instance.get()), static_cast<double>(0.0));
245
246 mirror::ArtField* objectField = sirt_klass->FindDeclaredInstanceField("objectField", "Ljava/lang/Object;");
247 ASSERT_TRUE(objectField != nullptr);
248 ASSERT_EQ(FieldHelper(objectField).GetTypeAsPrimitiveType(), Primitive::kPrimNot);
249 ASSERT_EQ(objectField->GetObject(sirt_instance.get()), nullptr);
250
251 // Create a java.lang.Object instance to set objectField.
252 SirtRef<mirror::Class> object_klass(soa.Self(), class_linker_->FindSystemClass("Ljava/lang/Object;"));
253 ASSERT_TRUE(object_klass.get() != nullptr);
254 SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
255 ASSERT_TRUE(sirt_obj.get() != nullptr);
256 ASSERT_EQ(sirt_obj->GetClass(), sirt_klass.get());
257
258 // Modify fields inside transaction and abort it.
259 Transaction transaction;
260 Runtime::Current()->EnterTransactionMode(&transaction);
261 booleanField->SetBoolean<true>(sirt_instance.get(), true);
262 byteField->SetByte<true>(sirt_instance.get(), 1);
263 charField->SetChar<true>(sirt_instance.get(), 1u);
264 shortField->SetShort<true>(sirt_instance.get(), 1);
265 intField->SetInt<true>(sirt_instance.get(), 1);
266 longField->SetLong<true>(sirt_instance.get(), 1);
267 floatField->SetFloat<true>(sirt_instance.get(), 1.0);
268 doubleField->SetDouble<true>(sirt_instance.get(), 1.0);
269 objectField->SetObject<true>(sirt_instance.get(), sirt_obj.get());
270 Runtime::Current()->ExitTransactionMode();
271 transaction.Abort();
272
273 // Check values have properly been restored to their original (default) value.
274 EXPECT_EQ(booleanField->GetBoolean(sirt_instance.get()), false);
275 EXPECT_EQ(byteField->GetByte(sirt_instance.get()), 0);
276 EXPECT_EQ(charField->GetChar(sirt_instance.get()), 0u);
277 EXPECT_EQ(shortField->GetShort(sirt_instance.get()), 0);
278 EXPECT_EQ(intField->GetInt(sirt_instance.get()), 0);
279 EXPECT_EQ(longField->GetLong(sirt_instance.get()), static_cast<int64_t>(0));
280 EXPECT_EQ(floatField->GetFloat(sirt_instance.get()), static_cast<float>(0.0f));
281 EXPECT_EQ(doubleField->GetDouble(sirt_instance.get()), static_cast<double>(0.0));
282 EXPECT_EQ(objectField->GetObject(sirt_instance.get()), nullptr);
283}
284
285
286TEST_F(TransactionTest, StaticArrayFieldsTest) {
287 ScopedObjectAccess soa(Thread::Current());
288 SirtRef<mirror::ClassLoader> class_loader(
289 soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")));
290 ASSERT_TRUE(class_loader.get() != nullptr);
291
292 SirtRef<mirror::Class> sirt_klass(soa.Self(),
293 class_linker_->FindClass("LStaticArrayFieldsTest;", class_loader));
294 ASSERT_TRUE(sirt_klass.get() != nullptr);
295 class_linker_->EnsureInitialized(sirt_klass, true, true);
296 ASSERT_TRUE(sirt_klass->IsInitialized());
297
298 // Lookup fields.
299 mirror::ArtField* booleanArrayField = sirt_klass->FindDeclaredStaticField("booleanArrayField", "[Z");
300 ASSERT_TRUE(booleanArrayField != nullptr);
301 mirror::BooleanArray* booleanArray = booleanArrayField->GetObject(sirt_klass.get())->AsBooleanArray();
302 ASSERT_TRUE(booleanArray != nullptr);
303 ASSERT_EQ(booleanArray->GetLength(), 1);
304 ASSERT_EQ(booleanArray->GetWithoutChecks(0), false);
305
306 mirror::ArtField* byteArrayField = sirt_klass->FindDeclaredStaticField("byteArrayField", "[B");
307 ASSERT_TRUE(byteArrayField != nullptr);
308 mirror::ByteArray* byteArray = byteArrayField->GetObject(sirt_klass.get())->AsByteArray();
309 ASSERT_TRUE(byteArray != nullptr);
310 ASSERT_EQ(byteArray->GetLength(), 1);
311 ASSERT_EQ(byteArray->GetWithoutChecks(0), 0);
312
313 mirror::ArtField* charArrayField = sirt_klass->FindDeclaredStaticField("charArrayField", "[C");
314 ASSERT_TRUE(charArrayField != nullptr);
315 mirror::CharArray* charArray = charArrayField->GetObject(sirt_klass.get())->AsCharArray();
316 ASSERT_TRUE(charArray != nullptr);
317 ASSERT_EQ(charArray->GetLength(), 1);
318 ASSERT_EQ(charArray->GetWithoutChecks(0), 0u);
319
320 mirror::ArtField* shortArrayField = sirt_klass->FindDeclaredStaticField("shortArrayField", "[S");
321 ASSERT_TRUE(shortArrayField != nullptr);
322 mirror::ShortArray* shortArray = shortArrayField->GetObject(sirt_klass.get())->AsShortArray();
323 ASSERT_TRUE(shortArray != nullptr);
324 ASSERT_EQ(shortArray->GetLength(), 1);
325 ASSERT_EQ(shortArray->GetWithoutChecks(0), 0);
326
327 mirror::ArtField* intArrayField = sirt_klass->FindDeclaredStaticField("intArrayField", "[I");
328 ASSERT_TRUE(intArrayField != nullptr);
329 mirror::IntArray* intArray = intArrayField->GetObject(sirt_klass.get())->AsIntArray();
330 ASSERT_TRUE(intArray != nullptr);
331 ASSERT_EQ(intArray->GetLength(), 1);
332 ASSERT_EQ(intArray->GetWithoutChecks(0), 0);
333
334 mirror::ArtField* longArrayField = sirt_klass->FindDeclaredStaticField("longArrayField", "[J");
335 ASSERT_TRUE(longArrayField != nullptr);
336 mirror::LongArray* longArray = longArrayField->GetObject(sirt_klass.get())->AsLongArray();
337 ASSERT_TRUE(longArray != nullptr);
338 ASSERT_EQ(longArray->GetLength(), 1);
339 ASSERT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
340
341 mirror::ArtField* floatArrayField = sirt_klass->FindDeclaredStaticField("floatArrayField", "[F");
342 ASSERT_TRUE(floatArrayField != nullptr);
343 mirror::FloatArray* floatArray = floatArrayField->GetObject(sirt_klass.get())->AsFloatArray();
344 ASSERT_TRUE(floatArray != nullptr);
345 ASSERT_EQ(floatArray->GetLength(), 1);
346 ASSERT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
347
348 mirror::ArtField* doubleArrayField = sirt_klass->FindDeclaredStaticField("doubleArrayField", "[D");
349 ASSERT_TRUE(doubleArrayField != nullptr);
350 mirror::DoubleArray* doubleArray = doubleArrayField->GetObject(sirt_klass.get())->AsDoubleArray();
351 ASSERT_TRUE(doubleArray != nullptr);
352 ASSERT_EQ(doubleArray->GetLength(), 1);
353 ASSERT_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
354
355 mirror::ArtField* objectArrayField = sirt_klass->FindDeclaredStaticField("objectArrayField", "[Ljava/lang/Object;");
356 ASSERT_TRUE(objectArrayField != nullptr);
357 mirror::ObjectArray<mirror::Object>* objectArray = objectArrayField->GetObject(sirt_klass.get())->AsObjectArray<mirror::Object>();
358 ASSERT_TRUE(objectArray != nullptr);
359 ASSERT_EQ(objectArray->GetLength(), 1);
360 ASSERT_EQ(objectArray->GetWithoutChecks(0), nullptr);
361
362 // Create a java.lang.Object instance to set objectField.
363 SirtRef<mirror::Class> object_klass(soa.Self(), class_linker_->FindSystemClass("Ljava/lang/Object;"));
364 ASSERT_TRUE(object_klass.get() != nullptr);
365 SirtRef<mirror::Object> sirt_obj(soa.Self(), sirt_klass->AllocObject(soa.Self()));
366 ASSERT_TRUE(sirt_obj.get() != nullptr);
367 ASSERT_EQ(sirt_obj->GetClass(), sirt_klass.get());
368
369 // Modify fields inside transaction and abort it.
370 Transaction transaction;
371 Runtime::Current()->EnterTransactionMode(&transaction);
372 booleanArray->SetWithoutChecks<true>(0, true);
373 byteArray->SetWithoutChecks<true>(0, 1);
374 charArray->SetWithoutChecks<true>(0, 1u);
375 shortArray->SetWithoutChecks<true>(0, 1);
376 intArray->SetWithoutChecks<true>(0, 1);
377 longArray->SetWithoutChecks<true>(0, 1);
378 floatArray->SetWithoutChecks<true>(0, 1.0);
379 doubleArray->SetWithoutChecks<true>(0, 1.0);
380 objectArray->SetWithoutChecks<true>(0, sirt_obj.get());
381 Runtime::Current()->ExitTransactionMode();
382 transaction.Abort();
383
384 // Check values have properly been restored to their original (default) value.
385 EXPECT_EQ(booleanArray->GetWithoutChecks(0), false);
386 EXPECT_EQ(byteArray->GetWithoutChecks(0), 0);
387 EXPECT_EQ(charArray->GetWithoutChecks(0), 0u);
388 EXPECT_EQ(shortArray->GetWithoutChecks(0), 0);
389 EXPECT_EQ(intArray->GetWithoutChecks(0), 0);
390 EXPECT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
391 EXPECT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
392 EXPECT_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
393 EXPECT_EQ(objectArray->GetWithoutChecks(0), nullptr);
394}
395
396TEST_F(TransactionTest, EmptyClass) {
397 ScopedObjectAccess soa(Thread::Current());
398 SirtRef<mirror::ClassLoader> class_loader(
399 soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")));
400 ASSERT_TRUE(class_loader.get() != nullptr);
401
402 SirtRef<mirror::Class> sirt_klass(soa.Self(),
403 class_linker_->FindClass("LTransaction$EmptyStatic;", class_loader));
404 ASSERT_TRUE(sirt_klass.get() != nullptr);
405 class_linker_->VerifyClass(sirt_klass);
406 ASSERT_TRUE(sirt_klass->IsVerified());
407
408 Transaction transaction;
409 Runtime::Current()->EnterTransactionMode(&transaction);
410 class_linker_->EnsureInitialized(sirt_klass, true, true);
411 Runtime::Current()->ExitTransactionMode();
412 ASSERT_FALSE(soa.Self()->IsExceptionPending());
413}
414
415TEST_F(TransactionTest, StaticFieldClass) {
416 ScopedObjectAccess soa(Thread::Current());
417 SirtRef<mirror::ClassLoader> class_loader(
418 soa.Self(), soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")));
419 ASSERT_TRUE(class_loader.get() != nullptr);
420
421 SirtRef<mirror::Class> sirt_klass(soa.Self(),
422 class_linker_->FindClass("LTransaction$StaticFieldClass;", class_loader));
423 ASSERT_TRUE(sirt_klass.get() != nullptr);
424 class_linker_->VerifyClass(sirt_klass);
425 ASSERT_TRUE(sirt_klass->IsVerified());
426
427 Transaction transaction;
428 Runtime::Current()->EnterTransactionMode(&transaction);
429 class_linker_->EnsureInitialized(sirt_klass, true, true);
430 Runtime::Current()->ExitTransactionMode();
431 ASSERT_FALSE(soa.Self()->IsExceptionPending());
432}
433
434TEST_F(TransactionTest, BlacklistedClass) {
435 ScopedObjectAccess soa(Thread::Current());
436 jobject jclass_loader = LoadDex("Transaction");
437 SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
438 soa.Decode<mirror::ClassLoader*>(jclass_loader));
439 ASSERT_TRUE(class_loader.get() != nullptr);
440
441 // Load and verify java.lang.ExceptionInInitializerError and java.lang.InternalError which will
442 // be thrown by class initialization due to native call.
443 SirtRef<mirror::Class> sirt_klass(soa.Self(),
444 class_linker_->FindSystemClass("Ljava/lang/ExceptionInInitializerError;"));
445 ASSERT_TRUE(sirt_klass.get() != nullptr);
446 class_linker_->VerifyClass(sirt_klass);
447 ASSERT_TRUE(sirt_klass->IsVerified());
448 sirt_klass.reset(class_linker_->FindSystemClass("Ljava/lang/InternalError;"));
449 ASSERT_TRUE(sirt_klass.get() != nullptr);
450 class_linker_->VerifyClass(sirt_klass);
451 ASSERT_TRUE(sirt_klass->IsVerified());
452
453 // Load and verify Transaction$NativeSupport used in class initialization.
454 sirt_klass.reset(class_linker_->FindClass("LTransaction$NativeSupport;", class_loader));
455 ASSERT_TRUE(sirt_klass.get() != nullptr);
456 class_linker_->VerifyClass(sirt_klass);
457 ASSERT_TRUE(sirt_klass->IsVerified());
458
459 sirt_klass.reset(class_linker_->FindClass("LTransaction$BlacklistedClass;", class_loader));
460 ASSERT_TRUE(sirt_klass.get() != nullptr);
461 class_linker_->VerifyClass(sirt_klass);
462 ASSERT_TRUE(sirt_klass->IsVerified());
463
464 Transaction transaction;
465 Runtime::Current()->EnterTransactionMode(&transaction);
466 class_linker_->EnsureInitialized(sirt_klass, true, true);
467 Runtime::Current()->ExitTransactionMode();
468 ASSERT_TRUE(soa.Self()->IsExceptionPending());
469}
470
471
472} // namespace art