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