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 
25 namespace art {
26 
27 class TransactionTest : public CommonRuntimeTest {};
28 
TEST_F(TransactionTest,Object_class)29 TEST_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 
TEST_F(TransactionTest,Object_monitor)48 TEST_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 
TEST_F(TransactionTest,Array_length)76 TEST_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 
TEST_F(TransactionTest,StaticFieldsTest)103 TEST_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(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 
TEST_F(TransactionTest,InstanceFieldsTest)198 TEST_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(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 
TEST_F(TransactionTest,StaticArrayFieldsTest)298 TEST_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(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 
TEST_F(TransactionTest,EmptyClass)412 TEST_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(h_klass);
423   ASSERT_TRUE(h_klass->IsVerified());
424 
425   Transaction transaction;
426   Runtime::Current()->EnterTransactionMode(&transaction);
427   class_linker_->EnsureInitialized(h_klass, true, true);
428   Runtime::Current()->ExitTransactionMode();
429   ASSERT_FALSE(soa.Self()->IsExceptionPending());
430 }
431 
TEST_F(TransactionTest,StaticFieldClass)432 TEST_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(h_klass);
444   ASSERT_TRUE(h_klass->IsVerified());
445 
446   Transaction transaction;
447   Runtime::Current()->EnterTransactionMode(&transaction);
448   class_linker_->EnsureInitialized(h_klass, true, true);
449   Runtime::Current()->ExitTransactionMode();
450   ASSERT_FALSE(soa.Self()->IsExceptionPending());
451 }
452 
TEST_F(TransactionTest,BlacklistedClass)453 TEST_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   Handle<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(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(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(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(h_klass);
485   ASSERT_TRUE(h_klass->IsVerified());
486 
487   Transaction transaction;
488   Runtime::Current()->EnterTransactionMode(&transaction);
489   class_linker_->EnsureInitialized(h_klass, true, true);
490   Runtime::Current()->ExitTransactionMode();
491   ASSERT_TRUE(soa.Self()->IsExceptionPending());
492 }
493 
494 
495 }  // namespace art
496